您可以使用AspectJ基於切入點聲明錯誤和/或警告的能力。
免責聲明:我從來沒有使用過春節,所以我不是專家那裏,只是做了一個例子沒有多大意義的示範。
Spring Bean與原型範圍:
package de.scrum_master.app;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
public class ScopedBean {}
的Spring bean缺少範圍聲明:
package de.scrum_master.app;
import org.springframework.stereotype.Component;
@Component
public class UnscopedBean {}
的Spring bean使用不同類型的自動佈線:
這個bean使用構造函數和setter方法連線。如果取消註釋字段聲明中的註釋,則甚至可以使用其他類型的接線。這沒有任何意義,但我們希望在稍後的某個方面引發編譯錯誤。
package de.scrum_master.app;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("singleton")
public class BeanWithAutowire {
//@Autowired
private ScopedBean scopedBean;
@Autowired
public BeanWithAutowire(ScopedBean scopedBean) {
this.scopedBean = scopedBean;
}
@Autowired
public void setScopedBean(ScopedBean scopedBean) {
this.scopedBean = scopedBean;
}
}
方面的用於靜態註釋一致性檢查:
package de.scrum_master.aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
public aspect BeanAnnotationChecker {
declare error :
@annotation(Component) && [email protected](Scope) :
"Spring component without scope declaration found";
declare error :
execution(@Autowired *.new(.., @Scope("prototype") *, ..)) && within(@Scope("singleton") *) :
"singleton bean auto-wired into prototype container via constructor";
declare error :
execution(@Autowired * *(.., @Scope("prototype") *, ..)) && within(@Scope("singleton") *) :
"singleton bean auto-wired into prototype container via setter method";
declare error :
set(@Autowired * *) && within(@Scope("singleton") *) :
"singleton bean auto-wired into prototype container via field assignment";
}
Maven的POM使用AspectJ編譯器:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.scrum-master.stackoverflow</groupId>
<artifactId>aspectj-fail-build</artifactId>
<version>1.0-SNAPSHOT</version>
<name>AspectJ - fail build for wrong/missing annotations</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.source-target.version>1.7</java.source-target.version>
<aspectj.version>1.8.4</aspectj.version>
<main-class>de.scrum_master.app.ScopedBean</main-class>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.source-target.version}</source>
<target>${java.source-target.version}</target>
<!-- IMPORTANT -->
<useIncrementalCompilation>false</useIncrementalCompilation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<configuration>
<showWeaveInfo>true</showWeaveInfo>
<source>${java.source-target.version}</source>
<target>${java.source-target.version}</target>
<Xlint>ignore</Xlint>
<complianceLevel>${java.source-target.version}</complianceLevel>
<encoding>UTF-8</encoding>
<verbose>true</verbose>
</configuration>
<executions>
<execution>
<!-- IMPORTANT -->
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.7.RELEASE</version>
</dependency>
</dependencies>
</project>
控制檯輸出mvn clean package
:
(...)
[INFO] ------------------------------------------------------------------------
[INFO] Building AspectJ - fail build for wrong/missing annotations 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
(...)
[ERROR] singleton bean auto-wired into prototype container via constructor
C:\Users\Alexander\Documents\java-src\SO_AJ_MavenFailBuildOnWrongAnnotation\src\main\java\de\scrum_master\app\BeanWithAutowire.java:14
public BeanWithAutowire(ScopedBean scopedBean) {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[ERROR] singleton bean auto-wired into prototype container via setter method
C:\Users\Alexander\Documents\java-src\SO_AJ_MavenFailBuildOnWrongAnnotation\src\main\java\de\scrum_master\app\BeanWithAutowire.java:19
public void setScopedBean(ScopedBean scopedBean) {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[ERROR] Spring component without scope declaration found
C:\Users\Alexander\Documents\java-src\SO_AJ_MavenFailBuildOnWrongAnnotation\src\main\java\de\scrum_master\app\UnscopedBean.java:6
public class UnscopedBean {}
^^^^^^^^^^^
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
(...)
我認爲這個例子除了AspectJ語法之外有些不言自明,但您可以在AspectJ手冊或教程中閱讀更多關於它的信息。如果在字段聲明中取消對@Autowired
註釋的註釋,則將顯示更多錯誤以用於顯式字段分配。不過,AspectJ無法在單純的字段聲明(不帶任務)上匹配。因此,無論您的開發人員何時依賴字段註釋而不是註釋的構造函數或設置方法,即您的代碼中沒有任何明確的字段分配,都不會出現編譯錯誤。您可以通過匹配getter方法或代碼中的字段讀訪問來間接地匹配字段來解決此問題。如果你自己無法弄清楚,請隨時詢問如何做到這一點。
我不知道用Spring本身進行驗證。您可以使用自定義PMD或FindBugs規則來執行此操作。 – user944849 2014-11-21 20:28:23
你可以看看maven-enforcer-plugin,你可以實現自己的規則,這可能是你的一條路徑...... – khmarbaise 2014-11-22 17:05:43