簡體   English   中英

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

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

最近在 Spring Boot 應用程序中被Spring CGLib 與 JDK 動態代理問題所困擾(在 Mac 上運行時似乎使用 CGLib,而在 Linux 上運行時使用 JDK 動態代理的同一個應用程序)。

我正在尋找一個 linter 工具配置/插件(PMD、Checkstyle、Spotbugs 等),它可以識別 @Autowired 注釋字段/參數的使用位置,並且自動裝配的類是用類實例而不是接口定義的。

例如:

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 項目通常是一個好主意,它們還具有可在項目中使用的預配置模板。 希望這可以幫助。

除了上面@VyomYdv 的回答之外,我偶然發現了這個 github 問題的春季: https ://github.com/spring-projects/spring-boot/issues/8277

本質上,使用@Validated@ConfigurationProperties注釋並且還實現接口的bean 將成為運行時JDK 代理實例的候選對象,並且您不能自動裝配類實例,您必須作為接口自動裝配。

所以修改YyomYdv的規則如下:

public static final ArchRule AUTOWIRE_PROXY_RULE = noFields()
    .that()
    .areAnnotatedWith(Autowired.class)
    .should()
    .haveRawType(new DescribedPredicate<>("that does not autowire an interface") {
        @Override
        public boolean apply(final JavaClass input) {
            return !input.isInterface();
        }
    })
    .andShould().haveRawType(new DescribedPredicate<>("class is not a JDK proxy candidate") {
        @Override
        public boolean apply(final JavaClass input) {
            return !input.getAllRawInterfaces().isEmpty()
                && input.getPackageName().startsWith("com.mypackage")
                && input.isAnnotatedWith(Validated.class)
                && input.isAnnotatedWith(ConfigurationProperties.class);
        }
    });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM