博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
代码质量之Archunit的使用
阅读量:6306 次
发布时间:2019-06-22

本文共 5910 字,大约阅读时间需要 19 分钟。

hot3.png

    注:开发的编辑器: Intellij Idea,JDK版本是JDK8

    是什么,官网的英文介绍很好,建议阅读原文,"ArchUnit is a free, simple and extensible library for checking the architecture of your Java code using any plain Java unit test framework. That is, ArchUnit can check dependencies between packages and classes, layers and slices, check for cyclic dependencies and more"。

    简单来说,它是代码格式、类之间的依赖关系检查工具。

  1. 进入官网
  2. 点击右上角的"User Gruide"
  3. 之后就可以看到它的英文教程文档。

1.pom.xml中加入依赖

    List-1 最重要的是archunit-junit4依赖

junit
junit
4.12
test
com.tngtech.archunit
archunit-junit4
0.9.1
test

2.添加规则

    直接上代码了,如下List-2所示,按项目情况,修改自己的"@AnalyzeClasses的packages值"

    List-2

import javax.persistence.Entity;import com.tngtech.archunit.junit.AnalyzeClasses;import com.tngtech.archunit.junit.ArchTest;import com.tngtech.archunit.junit.ArchUnitRunner;import com.tngtech.archunit.lang.ArchRule;import org.junit.runner.RunWith;import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;import static com.tngtech.archunit.library.GeneralCodingRules.NO_CLASSES_SHOULD_ACCESS_STANDARD_STREAMS;import static com.tngtech.archunit.library.GeneralCodingRules.NO_CLASSES_SHOULD_THROW_GENERIC_EXCEPTIONS;import static com.tngtech.archunit.library.GeneralCodingRules.NO_CLASSES_SHOULD_USE_JAVA_UTIL_LOGGING;/** * @author dmj1161859184@126.com 2018-09-14 23:03 * @version 1.0 * @since 1.0 */@RunWith(ArchUnitRunner.class) // Remove this line for JUnit 5!!@AnalyzeClasses(packages = "com.mjduan.project") //要扫描的packagepublic class ArchunitTest {    /** dao下的类应该以Dao结尾 */    @ArchTest    public static final ArchRule DAOs_must_reside_in_a_dao_package = classes()            .that()            .haveNameMatching(".*Dao")            .should()            .resideInAPackage("..dao..")            .as("DAOs should reside in a package '..dao..'");    /** controller下的类应该以Controller结尾 */    @ArchTest    public static final ArchRule CONTROLLERs_must_reside_in_a_dao_package = classes()            .that()            .haveNameMatching(".*Controller")            .should()            .resideInAPackage("..controller..")            .as("DAOs should reside in a package '..dao..'");    /** util下的类应该以Util结尾 */    @ArchTest    public static final ArchRule UTILs_must_reside_in_a_dao_package = classes()            .that()            .haveNameMatching(".*Util")            .should()            .resideInAPackage("..util..")            .as("DAOs should reside in a package '..dao..'");    /** 有Entity注解的类,应该在domain或者entity包下 */    @ArchTest    public static final ArchRule entities_must_reside_in_a_domain_package = classes()            .that()            .areAnnotatedWith(Entity.class)            .should()            .resideInAnyPackage("..domain..", "..entity..");    /** 接口类,应该以I开头 */    @ArchTest    public static final ArchRule interface_className_must_start_with_I = classes()            .that()            .areInterfaces()            .should()            .haveSimpleNameStartingWith("I")            .as("Interface should start with I");    /** service下的类,只能被controller下或者时service下的类访问 */    @ArchTest    public static final ArchRule services_should_only_be_accessed_by_controllers_or_other_services = classes()            .that()            .resideInAPackage("..service..")            .should()            .onlyBeAccessed()            .byAnyPackage("..controller..", "..service..");    /** impl下的类,不能是interface */    @ArchTest    public static final ArchRule interfaces_must_not_be_placed_in_implementation_packages = noClasses()            .that()            .resideInAPackage("..impl..")            .should()            .beInterfaces();    /** 接口类,类名不能以Interface结尾 */    @ArchTest    public static final ArchRule interfaces_should_not_have_names_ending_with_the_word_interface = noClasses()            .that()            .areInterfaces()            .should()            .haveNameMatching(".*Interface");    /** service下的类,不能调用controller下的类 */    @ArchTest    public static final ArchRule services_should_not_access_controllers = noClasses()            .that()            .resideInAPackage("..service..")            .should()            .accessClassesThat()            .resideInAPackage("..controller..");    /** dao下的类,不能调用controller下的类 */    @ArchTest    public static final ArchRule controllers_should_not_access_dao = noClasses()            .that()            .resideInAPackage("..dao..")            .should()            .accessClassesThat()            .resideInAnyPackage("..controller..");    /** 不应该使用System.* */    @ArchTest    private final ArchRule NO_ACCESS_TO_STANDARD_STREAMS = NO_CLASSES_SHOULD_ACCESS_STANDARD_STREAMS;    /** 不应该抛出Exception */    @ArchTest    private final ArchRule NO_GENERIC_EXCEPTIONS = NO_CLASSES_SHOULD_THROW_GENERIC_EXCEPTIONS;    /** 不应该使用java.util.logging来记录日志 */    @ArchTest    private final ArchRule NO_JAVA_UTIL_LOGGING = NO_CLASSES_SHOULD_USE_JAVA_UTIL_LOGGING;}

    List-2中的代码中已经给出注释,自己可以在项目中运行看下结果。不过发现有个不好的地方是,archunit会扫描test下的类。

    注:如果要忽略某个规则,那么加上@ArchIgnore就可以了,参考。

2.1 忽略某个规则

    List-3

public class ArchitectureTest {    // will run    @ArchTest    public static final ArchRule rule1 = classes().should()...    // won't run    @ArchIgnore    @ArchTest    public static final ArchRule rule2 = classes().should()...}

2.2 忽略多个类,即不让Archunit扫描多个类

    一般出现在遗留系统中。

                     

                                                            图2.1 

    比如我们想在Archunit扫描时,忽略DemoInterface和AnnotationDemo,那么在resources下建个"archunit_ignore_patterns.txt"的文件(这个文件名称是固定的,不能修改),在将要忽略的类路径放入其中,注意格式,如下图2.2所示,参考其。

    

                                                            图2.2

3.Demo

    新建一个interface,名为DemoInterface,之后运行List-2,结果如下图1所示,由于DemoInterface是interface,类名以Interface结尾(List-2中定义不能以Interface结尾),未以I开头(List-2中定义要以I开头):

                                                    图3.1  运行List-2后报错信息

4.官方的Archunit example

    可以在Github上看Archunit的例子,Github地址:     

    实际项目中,代码量较多,规范要做好,特别是人员流动是公司中很常见的。

转载于:https://my.oschina.net/u/2518341/blog/2051680

你可能感兴趣的文章
js中退出语句break,continue和return(语句详解)
查看>>
Android 学习笔记(一)
查看>>
node.js学习网址
查看>>
Tomcat学习总结(7)——Tomcat与Jetty比较
查看>>
js获取当前时间的前一天/后一天
查看>>
开博第一天
查看>>
代码轮子之很简单但是挺管用的基于C# Task的模拟并发的代码
查看>>
《亲爱的界面,让用户乐于使用、爱不释手》小编推介
查看>>
【转】.NET正则基础——.NET正则类及方法应用
查看>>
【视频编解码·学习笔记】13. 提取PPS信息程序
查看>>
数学 - 线性代数导论 - #5 矩阵变换之置换与转置
查看>>
java数据结构:队列
查看>>
IPsec工具之ipsec-tools
查看>>
jmeter文件下载
查看>>
Selenium2Library系列 keywords 之 _SelectElementKeywords 之 get_selected_list_labels(self, locator)...
查看>>
ASP.NET 中执行 URL 重写
查看>>
JS从定义到执行
查看>>
第七周学习报告
查看>>
10分钟学会在Ubuntu 18.04 LTS上安装NFS服务器和客户端
查看>>
Shell编程笔记
查看>>