植物百科网
当前位置: 首页 农业百科

idea代码规范包(外来规范水土不服)

时间:2023-07-10 作者: 小编 阅读量: 1 栏目名: 农业百科

外来规范水土不服本文字数:2007字阅读时间:7分钟导读很多公司都在用阿里巴巴的Java开发规范,本文会简要谈一下规范的必要性,然后介绍两个底层原理最后,手把手教你怎么扩展阿里巴巴Java开发规范插件:P3C,添加你。

本文字数:2007字

阅读时间:7分钟


导读

很多公司都在用阿里巴巴的Java开发规范,本文会简要谈一下规范的必要性,然后介绍两个底层原理。最后,手把手教你怎么扩展阿里巴巴Java开发规范插件:P3C,添加你的自定义规则。


本心法注重内功修养,普通人修炼需要三个月,而任督二脉打通之高手,三个小时即可炼成。


任督二脉打通条件如下:


1. 熟悉maven

2. 熟悉gradle

3. 熟悉pmd

4. 经常抓网站(熟悉xpath)

5. 会写java代码


一、为什么要定制规范

代码是谁维护?是gitlab?还是jdk?说到底,还是程序猿这些人类来维护!


代码首先是给人看的,其次才是给机器。没人能读懂,也没人能维护的代码那就是个渣 ( ̄_, ̄ )


那么,问题来了,如何编写出任何人都看到懂的代码?答:制——定——规——范


然后,问题又来了,虽然每个公司都有自己的编码规范,但往往出于赶进度、怠惰、个人心情&水平&习惯等原因,加之没有review,最后的代码就让人望而生畏。


规范有了没人遵守,怎么强制执行呢? 答:交——给——工——具!(哎~看这锅甩的弧线像不像研发的泪?)


本文通过介绍java静态代码检查工具PMD阿里巴巴p3c开源项目,让你学会怎么潇洒的制定自己的代码规范,解放你的双手,以及滔滔不绝的说教。


二、基本原理

古人云,君子生非异也,善假于物也。意思是大佬都是会借力的,可四两拨千斤。现在就介绍下本期的千斤顶


1、PMD静态代码扫描

1.1 概述

PMD(Project Manager Design)是一种开源分析Java代码错误的工具,它通过静态分析获知代码错误。即在不运行Java程序的情况下报告错误。其本身附带了许多可以直接使用的规则,利用这些规则可以找出Java源程序的许多问题。


例如:


潜在的bug:空的if/try/catch/finally/switch语句 ;

未使用的代码:未使用的局部变量、参数、私有方法等 ;

可选的代码:String/StringBuffer的滥用 ;

复杂的表达式:不必须的if语句、可以使用while循环完成的for循环;

重复的代码:糊代码==糊bug ;

循环体创建新对象:创建对象一时爽,一直创建一直爽 ;

资源关闭:Connect,Result,Statement等使用之后确保关闭 。


此外,用户还可以自己定义规则,检查Java代码是否符合某些特定的编码规范。例如,你可以编写一个规则,要求PMD找出所有创建Thread和Socket对象的操作


1.2 工作原理


PMD的核心是JavaCC解析器生成器。其结合运用JavaCC和EBNF(扩展巴科斯-诺尔范式,Extended Backus-Naur Formal)语法,再加上JJTree,把Java源代码解析成抽象语法树(AST,Abstract Syntax Tree)


从根本上看,Java源代码只是一些普通的文本。不过,为了让解析器承认 这些普通的文本是合法的Java代码,它们必须符合某种特定的结构要求。


这种结构可以用一种称为EBNF的句法元语言表示,通常称为“语法” (Grammar)。JavaCC根据语法要求生成解析器,这个解析器就可以用于解析用Java编程语言编写的程序。


1.3 规则分类


最佳实践:公认的最佳实践的规则


代码风格:这些规则强制执行特定的编码风格


设计:帮助您发现设计问题的规则


文档: 这些规则与代码文档有关


容易出错的规则: 用于检测被破坏的、非常混乱的或容易发生运行时错误的结构的规则


多线程:这些规则在处理多个执行线程时标记问题


性能:标记存在性能问题的代码的规则


安全:显示潜在安全缺陷的规则


2、阿里巴巴Java开发规约插件p3c


p3c主要包含三个部分:


p3c-pmd ,大部分规则实现,基于PMD开发,若想实现自己的规则,可基于此模块开发(基于maven编译打包)

idea-plugin , IntelliJ IDEA插件(基于gradle编译打包)


三、如何做?

说了这么多,那到底怎么扩展p3c编写自定义规则呢?( ͡° ͜ʖ ͡°)


1、自定义规则设计

以常用的spring-mvc为例。

假设,需要开发一个规则:方法上的@RequestMapping 注解需指定method参数。(不然swagger生成文档能生出一堆葫芦娃)


1//前方swagger葫芦娃预警 2@RequestMapping("/hehe") 3public String sayHeHe() { 4return "hehe"; 5} 6//仅GET、POST方法 7@RequestMapping(value = "/hehe",method = {RequestMethod.GET,RequestMethod.POST}) 8public String sayHeHe() { 9return "hehe";10}

2、准备阶段

下载PMD

拉P3C代码

冲杯咖啡 (o≖◡≖)


3、PMD图形化工具

解压PMD,打开/pmd-bin-6.17.0/bin/designer.bat

使用图形化工具构建语法树,揪出问题代码。



相关代码如下:


1package com.test.rest.controller; 2 3import lombok.extern.Slf4j.Slf4j; 4import org.springframework.beans.factory.annotation.Autowired; 5import org.springframework.web.bind.annotation.RequestMapping; 6import org.springframework.web.bind.annotation.RestController; 7import java.util.List; 8 9@Slf4j10@RestController11@RequestMapping("/test")12public class TestController {13@RequestMapping(value="/hehe",method = {RequestMethod.GET,RequestMethod.POST})14public String sayHeHe() {15return "hehe";16}17@RequestMapping("/heihei")18public String sayHeiHei() {19return "heihei";20}21@RequestMapping(value="/haha")22public String sayHaHa() {23return "haha";24}25}


4、分析语法树

可以看到,整棵树的根节点是CompilationUnit,即编译单元,代表每个java源文件。


我们首先要找到@RequestMapping的位置,点击相应的节点,看看光标是否定位到源码方法声明位置。


仔细分析ClassOrInterfaceBody,发现存在Annotation节点,这就是我们需要下手的地方了。



注意,由于写法不同,被分为了NormalAnnotation及SingleMemberAnnotation,为了后续处理XPath可以这么写:


1//ClassOrInterfaceBody//Annotation[@AnnotationName='RequestMapping']


来验证一下表达式是否正确,将它丢到PMD图形界面XPATH Expression框中:



5、p3c-pmd编写

打开p3c-pmd工程,开始编写自定义规则。


阿里已经写了很多规则,我们现在要编写的规则属于面向对象范畴,可以把规则写到oop包下。


新建一个规则类RequestMappingRule,继承自AbstractAliRule,重写 visit方法:



相关代码:


1public class RequestMappingRule extends AbstractAliRule { 2private static final String IMPORT_XPATH = "//ImportDeclaration[@ImportedName='org.springframework.web.bind.annotation.RequestMapping']"; 3private static final String REQUESTMAPPING_XPATH = "//ClassOrInterfaceBody//Annotation[@AnnotationName='RequestMapping']"; 4private static final String METHOD_XPATH = "MemberValuePairs/MemberValuePair[@MemberName='method']"; 5@Override 6public Object visit(ASTCompilationUnit Node, Object data) { 7try { 8List<Node> importNodes = node.findChildNodesWithXPath(IMPORT_XPATH); 9if (null != importNodes && importNodes.size() > 0) {10List<Node> resquestMappingNodes = node.findChildNodesWithXPath(REQUESTMAPPING_XPATH);11Node annotation = null;12for (Node resquestMappingNode:resquestMappingNodes) {13annotation = resquestMappingNode.jjtGetChild(0);14if(annotation instanceof ASTSingleMemberAnnotation){15addViolationWithMessage(data, resquestMappingNode, "java.oop.RequestMappingRule.rule.msg", new Object[]{});16}else if(annotation instanceof ASTNormalAnnotation){17if(!annotation.hasDescendantMatchingXPath(METHOD_XPATH)){18addViolationWithMessage(data, resquestMappingNode, "java.oop.RequestMappingRule.rule.msg", new Object[]{});19}20}21}22}23} catch (Exception e) {24}25return super.visit(node, data);26}27}


6、规则配置

将编写好规则配置到ali-oop.xml文件中:



相关代码:


1<rule name="RequestMappingRule" 2language="java" 3message="java.oop.RequestMappingRule.rule.msg" 4> 5<description>java.oop.StringConcatRule.rule.msg.desc</description> 6<!--级别,1强制,2推荐,3参考--> 7<priority>2</priority> 8<example> 9<![CDATA[10Negative example:11@RequestMapping("/heihei")12@RequestMapping(value="/haha")13]]>14</example>15<example>16<![CDATA[17Positive example:18@RequestMapping(value="/hehe",method = {RequestMethod.GET,RequestMethod.POST})19]]>20</example>21</rule>


7、规则提示信息编写

上两步使用的提示信息和规则信息需要编写到message.xml配置文件中,message_en.xml中为英文提示,选修



8、单元测试

编写测试样例,将要测试的源代码写到test目录对应的xml文件中:



相关代码:


1<?xml version="1.0" encoding="UTF-8"?> 2<test-data xmlns="http://pmd.sourceforge.net/rule-tests" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.sourceforge.io/rule-tests_1_0_0.xsd"> 5<code-fragment > 6<![CDATA[ 7package com.test.rest.controller; 8 9import lombok.extern.slf4j.Slf4j;10import org.springframework.beans.factory.annotation.Autowired;11import org.springframework.web.bind.annotation.RequestMapping;12import org.springframework.web.bind.annotation.RestController;13import java.util.List;14@Slf4j15@RestController16@RequestMapping("/test")17public class TestController {18@RequestMapping(value="/hehe",method = {RequestMethod.GET,RequestMethod.POST})19public String sayHeHe() {20return "hehe";21}22@RequestMapping("/heihei")23public String sayHeiHei() {24return "heihei";25}26@RequestMapping(value="/haha")27public String sayHaHa() {28return "haha";29}30}31]]>32</code-fragment>33<test-code>34<description>RequestMapping use rule</description>35<expected-problems>0</expected-problems>36<expected-linenumbers>21,27</expected-linenumbers>37<code-ref />38</test-code>39</test-data>


编写单元测试:



运行单元测试,因为样例代码中21、27行不符合规范,但是我们预期问题个数写的是0,所以单元测试会不通过:



9、p3c-pmd打包


将p3c-pmd安装到本地maven仓库

先将不用的插件maven-javadoc-plugin 和maven-gpg-plugin注释掉,然后运行mvn命令:


1mvn -DskipTests=true clean install


idea-plugin插件打包

idea-plugin项目基于gradle构建,配置根目录下build.gradle,让构建使用本地私有maven仓库构建。



然后运行开始gradle构建:


1cd p3c-idea2gradle clean buildPlugin


打包成功后会在idea-plugin\p3c-idea\build\distributions\ 目录下生成Alibaba Java Coding Guidelines-1.0.0.zip 文件,这个就是我们加入了自己拓展阿里开发规约的插件。


IDEA安装后效果如下:



End

我很懒,懒得关注一些细如编码质量的问题。但我又想要写一些漂亮的代码,起码遵循规范的代码。借助工具,能够节省不少的力气,小伙伴们体验之后,也直呼好用。


这些,都是我值得欣慰的事情,也是让我懒下去的动力。


参考资料:

[1] https://pmd.github.io/

[2] https://pmd.github.io/pmd-6.4.0/pmd_rules_java_bestpractices.html

[3] https://pmd.github.io/pmd-6.4.0/pmd_rules_java_codestyle.html

[4] https://pmd.github.io/pmd-6.4.0/pmd_rules_java_design.html

[5] https://pmd.github.io/pmd-6.4.0/pmd_rules_java_documentation.html

[6] https://pmd.github.io/pmd-6.4.0/pmd_rules_java_errorprone.html

[7] https://pmd.github.io/pmd-6.4.0/pmd_rules_java_multithreading.html

[8] https://pmd.github.io/pmd-6.4.0/pmd_rules_java_performance.html

[9] https://pmd.github.io/pmd-6.4.0/pmd_rules_java_security.html

[10] https://github.com/alibaba/p3c

[11] https://pmd.github.io/

[12] https://github.com/alibaba/p3c

作者简介:小姐姐味道 (xjjdog),一个不允许程序员走弯路的公众号。聚焦基础架构和Linux。十年架构,日百亿流量,与你探讨高并发世界,给你不一样的味道。我的个人微信xjjdog0,欢迎添加好友,进一步交流。

,
    推荐阅读
  • 空气含量中最多的气体(空气含量中最多的气体介绍)

    空气中含量最多的气体是氮气,氮气约占空气体积分数的百分比约为78%。通过实验测定,空气的成分按体积计算,氮气大约占78%、氧气占21%、稀有气体0.94%、二氧化碳0.03%、其他气体和杂质0.03%,也就是说空气中含量最多的物质是氮气。氮气化学性质很不活泼,在高温高压及催化剂条件下才能和氢气反应生成氨气;在放电的情况下才能和氧气化合生成一氧化氮;即使Ca、Mg、Sr和Ba等活泼金属也只有在加热的情形下才能与其反应。

  • 文思豆腐羹如何做好吃(文思豆腐羹用什么豆腐)

    文思豆腐是一道有名的淮扬菜,需要的就是精湛的刀工,这样做出的文思豆腐会有嫩滑的口感,打造入口即化的口感。文思豆腐羹如何做好吃文思豆腐羹材料和做法步骤一、文思豆腐羹材料准备好豆腐400克,鸡脯肉,火腿还有香菇,再有准备好生菜,冬笋,调料需要准备盐和味精。

  • 结构性存款可以买理财吗(结构性存款是存款吗)

    雪球产品就是今年年初监管向信托公司进行窗口指导,要求叫停的产品。简单的说,这是一种高风险的金融衍生品,它通过持有一定结构的金融衍生品,来实现在某一特定情况下获利。这样的投资结构就能保证我不论涨,还是跌,只要在一定幅度内都可以盈利。交易期权等金融衍生品,是非常高风险的投资。

  • 正言厉色意思(正言厉色的意思)

    下面内容希望能帮助到你,我们来一起看看吧!正言厉色意思正言厉色,汉语成语,拼音是zhènɡyánlìsè,意思是形容板着脸,神情非常严厉。出自《汉书·王莽传》。宝玉突然想出一个主意,一本正经地给她讲扬州黛山林子洞耗子精偷香芋的故事,黛玉见他正言厉色,以为真有其事,后来才发现原来是在取笑她。

  • 面谈调薪酬有什么技巧(跟老板谈调薪的技巧有哪些)

    如果你在老板心目中分量很大,一般老板都会给你加薪的。和老板谈加薪时目的一定要明确,让老板知道你只是为了加薪,而不是辞职走人。和老板谈加薪后,一定要给老板一个考虑的时间,不要咄咄逼人,逼着老板加薪。老板也要有足够的思考时间,来考虑你是否值得加薪,给你加薪后对公司有没有什么影响。不仅口头上要表示感谢,工作中要更加努力,让老板觉得给你加薪是值得的。

  • 杏花有没有香味(杏花闻起来会特别香吗)

    杏树是中国著名的观赏树木,可配植于庭前、墙隅、道路旁、水边,也可群植、片植于山坡、水畔,是春季主要的观赏树种。杏花直径2至3厘米,先于叶开放。花梗短,长1至3毫米,被短柔毛。花萼紫绿色,萼筒圆筒形,外面基部被短柔毛。萼片卵形至卵状长圆形,先端急尖或圆钝,花后反折。花瓣圆形至倒卵形,白色或带红色,具短爪。

  • 减肥减肚子的方法(怎么减肚子呢)

    减肥减肚子的方法食用健康食品:酸奶与发酵的牛奶能激活消化必须的物质,有助于改善肠道微生物系统,从而防止腹部隆起。走路、喝水、按摩:走路及喝水有利腹部扁平。

  • 新坑翡翠手镯多少钱(新坑翡翠手镯的价格)

    新坑翡翠手镯多少钱?新坑翡翠手镯多少钱翡翠手镯作为大件翡翠制品,用料特别多,只有大块、质量好的翡翠原石才能打造成手镯,因此翡翠手镯的价格都比较高,商家们拿到质量比较好的原石也尽可能打造成手镯。具体到新坑种翡翠,因为大多数新坑种翡翠透明度都不高,质地也不够细腻,因此种水一般都是以糯种或豆种为主,极少出现冰种或冰种以上的种水,这样的翡翠价格价格自然不会太高,一个品质比较好的糯种翡翠手镯大概在十万以内。

  • 宁波毛蚶做法水煮几分钟(毛蚶煮多长时间可以吃)

    宁波毛蚶做法水煮几分钟毛蚬是很多人喜欢吃的食物,不过建议大家在做之前都要先用开水煮以下。强精益气,提高精液质量,增强精子活力。适用于治疗肾阳虚所致的阳痿、腰痛、小便频数及补五脏之气不足。可治疗全身水肿,小便不利等。能软化和保护血管,有降低人体中血脂和胆固醇的作用。

  • 2022洛阳湿地公园最新名单 洛阳生态公园最新消息

    国家级湿地自然保护区河南黄河湿地国家级自然保护区,面积24000公顷。国家级湿地公园嵩县陆浑湖国家湿地公园,面积4222.39公顷伊川伊河国家湿地公园,面积1384.36公顷。