Spring Boot @Autowired - checkstyle / pmd / spotbugs 规则以警告非接口使用

Spring Boot @Autowired - checkstyle / pmd / spotbugs rule to warn on non-interface usage

最近在 Spring 引导应用程序中遇到 Spring CGLib vs JDK Dynamic 代理问题(当 运行 在 Mac 上似乎使用 CGLib 时,作为同一个应用程序当 Linux 上的 运行 使用 JDK 动态代理时)。

我正在寻找一个 linter 工具配置/插件(PMD、Checkstyle、Spotbugs 等),它可以识别在哪里使用了 @Autowired 注释字段/参数,并且自动装配的 Class 定义为class 实例而不是接口。

例如:

public interface MyService {
}


public class MyServiceImpl implements MyService {
}


@RestController
public class MyController {
  @Autowired
  private MyServiceImpl serviceImpl;   // this should raise a warning in a linter as
                                       // class is being used for injection type

  @Autowired
  private MyService service;           // this should not raise a warning, as interface
                                       // is used for type
}

我认为这不可能通过 PMD、Checkstyle、Spotbugs 等进行检查。但是有一种解决方案可以检查这一点。 ArchUnit 提供编写自定义规则,可以为此编写自定义规则。假设您正在使用 JUnit5 或 JUnit4 进行测试,您可以执行以下操作:

@ArchTest                                         
public static final ArchRule archRule = noFields()
    .that()                                        
    .areAnnotatedWith(Autowired.class)             
    .should()                                      
    .haveNameEndingWith("Impl");                  

这可以合并到你的测试中,你必须阅读arch单元的文档并在你的工作环境中设置,它非常容易集成。您可以为设置器或方法创建类似的规则-

@ArchTest                                                         
public static final ArchRule archRule1 = noMethods()               
     .that()                                                       
     .areAnnotatedWith(Autowired.class)                       
     .should()                                                     
     .haveRawParameterTypes(MyServiceImpl.class, MyDaoImpl.class);

当您将其集成到您的代码库中时,您可以为自己创建自定义规则。将 ArchUnit 用于 spring 个项目通常是个好主意,它们也有预配置的模板,您可以在项目中使用。希望这有帮助。