一直在看DDD,自己感覺也可以搭建一個基本的開發環境了。但還是想綜合看一下别人的成果。axonframwork看了幾天了,感覺比isis更好上手,更加專注于領域模型,其他的事不管,挺好,而isis還有它自己定義的界面方案,不知道怎麼摘出來,可能是我不夠熟悉isis吧,感覺用的不舒服。之前讀了axon的quickstart和那個 addressbook例子。addressbook使用的是spring。可是我一直不用spring了(因為那個惡心的資料源死鎖問題),而是使用CDI來做注入之類的事情。我想把addressbook移植到CDI上,廢了不少周折才基本可用,下面就是我主要的改動,自己做個記錄。
主要問題:@CommandHandler,@EventHandler這種注解,可以直接放到一個pojo類的某個方法上,這樣就沒法通過普通的@Produces進行初始化,基本的java方式隻能是用實作CommandHandler接口來做,但這樣需要建立的handler類太多了。
另外,spring管理事務的功能肯定不能在cdi中使用了。
自己瞎鼓搗一陣子,基本注入都可以了,但是@CommandHandler和@EventHandler這種注解沒搞定,忽然從他的mailing list中看到有人寫了個axon-cdi的實作,在github上,能夠幫我解決不少問題,自己寫的話,CDI又要深入研究幾天了。多謝作者!如果你要找這個實作,直接去github上搜就行了。
下面說說我關鍵幾個地方的配置情況,使用maven:
首先,在pom.xml中配置庫的位址:
<repositories>
<repository>
<id>osc-repo</id>
<url>http://maven.oschina.net/content/groups/public/</url>
</repository>
<repository>
<id>public-repo2</id>
<url>http://repo2.maven.org/maven2/</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
<name>Jitpack.io Repository</name>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
其中主要是jitpack.io這個庫位址的配置,其他都是我自己配置的。這個配置允許從它的庫中下載下傳這個依賴,然後加上依賴的配置:
<dependency>
<groupId>com.github.kamaladafrica</groupId>
<artifactId>axon-cdi</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
這個庫我自己是直接下載下傳的zip源代碼,自己安裝的,你也可以這樣搞。
還有幾個依賴,是cdi擴充:apache-deltaspike,用于事務控制,axon-cdi也使用了deltaspike,也要加上:
<dependency>
<groupId>org.apache.deltaspike.core</groupId>
<artifactId>deltaspike-core-api</artifactId>
<version>1.6.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.deltaspike.core</groupId>
<artifactId>deltaspike-core-impl</artifactId>
<version>1.6.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.deltaspike.modules</groupId>
<artifactId>deltaspike-jpa-module-api</artifactId>
<version>1.6.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.deltaspike.modules</groupId>
<artifactId>deltaspike-jpa-module-impl</artifactId>
<version>1.6.0</version>
</dependency>
還有,axon-cdi自己有個例子,可以參照:axon-cdi-quickstart-master,同樣也在github上,然後根據這個例子的AxonConfiguration.java中的配置,自己修改一些自己使用的東西,入repository,主要是axon-cdi的@AutoConfigure注解,是幫助程式自動解析@CommandHandler、@EventHandler之類注解生成bean執行個體的。
axon-cdi-quickstart-master這個例子使用deltaspike的啟動和停止,直接運作的,但我的工程是個web工程(我把addressbook的api和webui工程整合到了一個工程裡面),是以,需要使用容器中的CDI環境。axon-cdi使用的是cdi-api 1.1版本,是以必須使用JavaEE7應用伺服器,我用的是WildFly8.2.0.Final。之前不清楚這個情況,在tomee1.7.4上部署,總沒有效果,因為tomee目前隻支援javaee6.
還有deltaspike-jpa-xxxx是cdi擴充,可以使用@Transactional注解來控制資料庫事務。使用這種方式控制事務,需要注意EntityManager的生成方式:EntityManager的producer應該這樣:
@ApplicationScoped
public class EntityManagerProducer {
@PersistenceUnit
private EntityManagerFactory entityManagerFactory;
@Produces
@Default
@RequestScoped
public EntityManager create()
{
return this.entityManagerFactory.createEntityManager();
}
public void dispose(@Disposes @Default EntityManager entityManager)
{
if (entityManager.isOpen())
{
entityManager.close();
}
}
}
使用EntityManagerFactory和@PersistenceUnit注解,在使用EntityManager的地方,應該使用@Inject注解,而不要直接使用@PersistenceContext注解,這種方式參考了官方文檔。這樣配置後,就可以在方法上直接加入@Transactional來指定事務控制了。
還有,我使用的是GenricJPARepository,例子原本用的是EventSourcedRepository,按照axon的要求聚合根必須使用jpa注解過的才可以,否則它不會儲存資料到contactentry表