はじめに
Gradle の Applicationプラグインで weld-se を使う場合、CDI管理の Bean の検索が beans.xml のあるファイルシステム上のパスを起点に行われてしまうため注意が必要。
CDI in Java SE (CDI2.0)
CDI 2.0 では Java EE 以外に、Java Standard Edition (SE) 向けのサポートが追加されている。
Weld では以前から Weld-se として提供されていたが、(準)標準API として javax
の名前空間で利用できるようになる。
CDI 2.0 仕様は EDR1 の状態であるが、weld のアルファ版で既に利用できる。
Main クラスの作成
エントリポイントの Main クラスを作成する。
package example; import javax.enterprise.inject.spi.CDI; public class Main { public static void main(String[] args) { try (CDI<Object> cdi = CDI.getCDIProvider().initialize()) { Application app = cdi.select(Application.class).get(); app.run(); } } }
CDI プロバイダを取得して初期化している。
Application クラスと Serviceクラスの作成
HelloService
を DI 対象とする Application
クラスを作成する。
package example; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sjwa.app.AccountService; import sjwa.app.SignUpReq; import sjwa.domain.Account; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; @ApplicationScoped public class Application { private static final Logger log = LoggerFactory.getLogger(Application.class); @Inject HelloService helloService; public void run() { String greeting = helloService.greeting(); log.info(greeting); } }
HelloService
は単に Hello!! を返却。
package example; import javax.enterprise.context.Dependent; @Dependent public class HelloService { public String greeting() { return "Hello !!"; } }
beans.xml
src/main/resources/META_INF/ 以下に beans.xml を作成する。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd" version="2.0" bean-discovery-mode="annotated"> </beans>
build.gradle
依存には weld-se-core
を指定する。
jandex
を追加することで、起動時の bean discovery が高速化される模様。
apply plugin: 'java' apply plugin: 'idea' apply plugin: 'application' sourceCompatibility = 1.8 targetCompatibility = 1.8 version = '1.0' mainClassName = "example.Main" repositories { jcenter() } dependencies { compile 'org.slf4j:slf4j-api:1.7.7' compile 'ch.qos.logback:logback-classic:1.1.3' compile 'org.jboss.weld.se:weld-se-core:3.0.0.Alpha14' compile 'org.jboss:jandex:2.0.1.Final' testCompile 'junit:junit:4.12' }
Gradle では、resources 以下に配備した beans.xml は build/resources/main/META-INF/beans.xml
に入り、コンパイル後のクラスファイルとはファイルシステム上別管理となる。
weld−se では bean discovery がファイルシステム上で beans.xml のあるディレクトリを起点に行われるため、このままだとweldが CDI 管理対象の bean を発見できない。
色々やり方はあるが、以下のようにリソースファイルを classes 配下にコピーしてしまうのが簡単。build.gradle に以下を追加する。
task copyResources(type: Copy) { from "${projectDir}/src/main/resources" into "${buildDir}/classes/main" } processResources.dependsOn copyResources
こちらを参照。
実行
$ ./gradlew clean build run
Hello !!
CDI - Dependency Injection in Java EE 6 (German Edition)
- 作者:Weil, Dirk
- 発売日: 2012/07/05
- メディア: Kindle版