CheckStyle规则之ImportControl

软件工程发展都到现在,“系统内部必须维持一定的层级关系,并确保每层之间的独立性”,关于这一点应该没有任何行内人士提出质疑,经典的MVC,MVVM等已经属于刚入门的萌新都能朗朗上口的概念。但认识是一回事,执行就成了另外一种情况的,Controller层中直接操作Dao的现象等往往并不罕见。

1. 背景

在本次推行自动化代码静态检查过程中,笔者在通读CheckStyle规则时偶然发现ImportControl规则能够非常完美地解决一些困扰笔者良久的问题。

官方文档对于规则ImportControl的解释为"可以用来控制哪些能够被引入,该规则可以细化到每个package或file。这对于确保项目的层级规则不被违反将是非常有帮助的,尤其是在于大型项目中"。

在日常开发中,我们经常会要求研发人员"不要在Controller层里写业务逻辑",“不要再调用这些过时的方法了”,"我们有封装的工具类,不要直接调用这些第三方库"等等。话说三遍淡如水与其一直人工盯着耗时耗力不讨好,还不如让忠诚可靠的机器来协助你。

2. 实践

关于ImportControl规则的使用介绍,官方文档里已经写得很详细了(底部链接不仅有官方示例,还有Tomcat源码中对该规则的使用示例),这里笔者仅给出自己使用这些典型样例(只是抛砖引玉,因此刚刚开始应用,还没来得及优化)。

import-control.xml文件



	
<import-control pkg="com.qqqq.zzzz" strategyOnMismatch="allowed">
  
  
  <allow pkg="java"/>
  <allow class="javax.imageio.ImageIO"/>
  <allow pkg="javax.management"/>
  <allow pkg="javax.naming"/>
  <allow pkg="javax.net"/>
  <allow pkg="javax.rmi"/>
  <allow pkg="javax.security"/>
  <allow pkg="javax.sql"/>
  <allow pkg="javax.xml"/>
  <allow pkg="org.w3c.dom"/>
  <allow pkg="org.xml.sax"/>
  <allow pkg="org.ietf.jgss"/>
    
  
  <disallow pkg="sun"/>
  <allow pkg="cn.hutool"/>

  
  <subpackage name="util" strategyOnMismatch="allowed">
	<disallow pkg="com\.qqqq\.zzzz\.jjjj" regex="true"/>
	
	
	<disallow class="com.qqqq.zzzz.plateform.dao.ICoreDao"/>	
	
	
	<disallow class="com.qqqq.qd.use.dao.ICoreDao"/>	
	<disallow class="com.qqqq.qd.use.service.IBaseService"/>
	<disallow class="com.qqqq.qd.use.service.impl.BaseServiceImpl"/>

	
	<disallow pkg="net\.sf\.json" regex="true" />
	<disallow pkg="com\.alibaba\.fastjson" regex="true" />
	<disallow pkg="com\.fasterxml\.jackson" regex="true" />
	

	
	<disallow class="java.text.SimpleDateFormat" />	
	
	
	<disallow class="com.qqqq.web.utils.SessionUtil"/>
	<disallow class="com.qqqq.support.web.utils.SessionUtil"/>

   	
	<disallow class="java.util.logging.Logger" />
   	<disallow class="org.apache.logging.log4j.Logger" />	
   	
	
	<disallow class=".*\.MD5" regex="true" />
	<disallow class=".*\.Resource" regex="true" />
	<disallow class=".*\.Base64Util" regex="true" />
	<disallow class=".*\.CompressedFileUtil" regex="true" />
	<disallow class=".*\.DataSourceUtil" regex="true" />
	<disallow class=".*\.DesUtil" regex="true" />
	<disallow class=".*].util\.FileUtil" regex="true" />	
  subpackage>

  
  
  
  
  <subpackage name="jjjj\.modules\.\w+\.action" regex="true" strategyOnMismatch="allowed">
	
	<disallow class="com.qqqq.zzzz.plateform.dao.ICoreDao"/>
	
	
	<disallow class="com.qqqq.qd.use.dao.ICoreDao"/>	
	<disallow class="com.qqqq.qd.use.service.IBaseService"/>
	<disallow class="com.qqqq.qd.use.service.impl.BaseServiceImpl"/>
	
	
	<disallow pkg="net\.sf\.json" regex="true" />
	<disallow pkg="com\.alibaba\.fastjson" regex="true" />
	<disallow pkg="com\.fasterxml\.jackson" regex="true" />

	
	<disallow class="java.text.SimpleDateFormat" />	
	
	
	<disallow class=".*\.MD5" regex="true" />
	<disallow class=".*\.Resource" regex="true" />
	<disallow class=".*\.Base64Util" regex="true" />
	<disallow class=".*\.CompressedFileUtil" regex="true" />
	<disallow class=".*\.DataSourceUtil" regex="true" />
	<disallow class=".*\.DesUtil" regex="true" />
	<disallow class=".*].util\.FileUtil" regex="true" />
	
  subpackage>
  
  
  
  
  
  <subpackage name="jjjj\.modules\.\w+\.service" regex="true" strategyOnMismatch="allowed">
	
	<disallow class="javax.servlet.http.HttpServletRequest"/>
	<disallow class="javax.servlet.http.HttpServletResponse"/>
	
	
	<disallow class="org.apache.struts2.ServletActionContext"/>
	<disallow class="com.opensymphony.xwork2.ActionSupport"/>
	
	
	<disallow class="com.qqqq.qd.use.dao.ICoreDao"/>
	
	
	<disallow pkg="net\.sf\.json" regex="true" />
	<disallow pkg="com\.alibaba\.fastjson" regex="true" />
	<disallow pkg="com\.fasterxml\.jackson" regex="true" />

	
	<disallow class="java.text.SimpleDateFormat" />	
	
	
	<disallow class=".*\.MD5" regex="true" />
	<disallow class=".*\.Resource" regex="true" />
	<disallow class=".*\.Base64Util" regex="true" />
	<disallow class=".*\.CompressedFileUtil" regex="true" />
	<disallow class=".*\.DataSourceUtil" regex="true" />
	<disallow class=".*\.DesUtil" regex="true" />
	<disallow class=".*].util\.FileUtil" regex="true" />

  subpackage> 
import-control>

3. 关联规则配置文件

最后将上面的ImportControll文件关联到主体规则配置文件中。




<module name="Checker">
	
	<module name="TreeWalker">
	
		<module name="ImportControl">
			<property name="file" value="D:/orgs/_checkstyle-pmd/import-control.xml"/>
			<property name="path" value="^.*[\\/]src[\\/]main[\\/].*$" />
		module>
		
		...
	module>

	...
module>

4. 注意事项

  1. 实践中我们发现ImportControl里定义的规则是有先后顺序的,因此指向性更明确的应该放在前面。例如下面两个规则:
  
  <subpackage name="xxxx\.modules\.\w+\.service\.impl" regex="true" strategyOnMismatch="allowed">
	<disallow class=".*" regex="true" />
  subpackage> 
  
  
  <subpackage name="xxxx\.modules\.\w+\.service"  regex="true" strategyOnMismatch="allowed">
	...
  subpackage>
  
  

5. 最后

借助机器,我们就能解放宝贵的人力来处理更多复杂性的问题,这不论对于企业还是员工本人都是有百利而无一害的事情。

6. Links

  1. Office Site - ImportControl Rule
  2. Office - import-control.xml示例
  3. Tomcat源码中对于ImportControl规则的使用
  4. SVN集成Checkstyle实现代码自动静态检查
  5. stackoverflow - checkstyle-rule-to-limit-interactions-between-root-packages-with-importcontrol
  6. stackoverflow - checkstyle-import-control-rule-for-src-folder

你可能感兴趣的:(DevOps,CheckStyle,DevOps,ImportControll)