Java EE 7 検証環境構築(5) JBoss Toolsが生成したサンプルソースのCDIを確認する
- Java EE 7 検証環境構築(1) WildFly + JBoss Tools で EARプロジェクトを作成し Arquillian で ユニットテストをグリーンにするところまで
- Java EE 7 検証環境構築(2) WildFly に DataSourceを作成
- Java EE 7 検証環境構築(3) JPAからMySQLに接続するユニットテストをArquillianで実行
- Java EE 7 検証環境構築(4) Java EE での DI(Dependency Injection) および CDI(Contexts and Dependency Injection)をながめる
- Java EE 7 検証環境構築(5) JBoss Toolsが生成したサンプルソースのCDIを確認する
- Java EE 7 検証環境構築(6) JPA エンティティの作成と挿入
- Java EE 7 検証環境構築(7) JPA 問い合わせ(1) 名前付きクエリを使ってみる。テストでトランザクションも意識する
- Java EE 7 検証環境構築(8) JPA 問い合わせ(2) 動的クエリとCriteria API を試す
- Java EE 7 検証環境構築(9) jBatch 概要をおさえる
- Java EE 7 検証環境構築(10) JBoss Tools で作成した EARプロジェクトをJava EE 6 から 7 に変更する
- Java EE 7 検証環境構築(11) jBatch用 プロジェクトの作成を行う
- Java EE 7 検証環境構築(12) jBatch 簡易サンプル作成と Arquillian でユニットテスト
- Java EE 7 検証環境構築(13) jBatch REST サービス経由で実行する
- Java EE 7 検証環境構築(14) WildFly の管理をGUIで行う
- Java EE 7 検証環境構築(15) WildFly を サービスとして設定する(Windows/Linux)
- Java EE 7 検証環境構築(16) WildFly と Apache を mod_jk で連携させる(Widows)
CDI の概要は何となく理解した。後は、どう使うのか。
まず、JBoss Tools で自動作成された EAR Project のサービスクラスを確認してみる。
- @Stateless
- public class MemberRegistration {
- @Inject
- private Logger log;
- @Inject
- private EntityManager em;
- @Inject
- private Event
memberEventSrc; public void register(Member member) throws Exception { log.info("Registering " + member.getName()); em.persist(member); memberEventSrc.fire(member); } }
さて、ここでインジェクトされている、Logger や EntityManager はどこで登録されているのかしら?
事前定義 Bean
事前定義された、Bean。もしかして事前定義されている?
http://docs.oracle.com/javaee/7/tutorial/doc/cdi-adv004.htm#CJGHGDBA
事前定義 | Resource or CDI Bean | インジェクション例 |
UserTransaction | Resource | @Resource UserTransaction transaction; |
Principal | Resource | @Resource Principal principal; |
Validator | Resource | @Resource Validator validator; |
ValidatorFactory | Resource | @Resource ValidatorFactory factory; |
HttpServletRequest | CDI Bean | @Inject HttpServletRequest req; |
HttpSession | CDI Bean | @Inject HttpSession session; |
ServletContext | CDI Bean | @Inject ServletContext context; |
の中には、ないようだ。
CDIが管理しているBeanをのぞいてみる
で、CDIが管理しているBeanの一覧を確認してみる。
Any bean may obtain an instance of BeanManager by injecting it:
@Inject BeanManager manager;
Arquillian テストケースで、BeanManager が管理しているBean一覧を出力
- @RunWith(Arquillian.class)
- public class BeanManagerTest {
- @Deployment
- public static Archive<?> createTestArchive() {
- return ShrinkWrap.create(WebArchive.class, "test.war")
- .addClasses(Resources.class)
- .addAsResource("META-INF/test-persistence.xml", "META-INF/persistence.xml")
- .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
- ;
- }
- @Inject
- Logger log;
- @Inject
- BeanManager manager;
- @Test
- public void testListAllBeans() throws Exception {
- @SuppressWarnings("serial")
- Set
<?>> beans = manager.getBeans(Object.class, new AnnotationLiteral (){}); for (Bean<?> bean: beans) { log.info(String.format( "BeanName=%s,Scope=%s", bean.getBeanClass().getName(), bean.getScope().getName())); } } }
結果(Sort & Unique 済み)。
- BeanName=com.sun.faces.application.view.ViewScopeExtension,Scope=javax.enterprise.context.ApplicationScoped
- BeanName=com.sun.faces.application.view.ViewScopedCDIEventFireHelperImpl,Scope=javax.enterprise.context.Dependent
- BeanName=com.sun.faces.flow.FlowCDIEventFireHelperImpl,Scope=javax.enterprise.context.Dependent
- BeanName=com.sun.faces.flow.FlowCDIExtension,Scope=javax.enterprise.context.ApplicationScoped
- BeanName=com.sun.faces.flow.FlowDiscoveryCDIExtension,Scope=javax.enterprise.context.ApplicationScoped
- BeanName=com.sun.faces.flow.FlowDiscoveryCDIHelper,Scope=javax.enterprise.context.Dependent
- BeanName=info.typea.tallarico.test.BeanManagerTest,Scope=javax.enterprise.context.Dependent
- BeanName=info.typea.tallarico.util.Resources,Scope=javax.enterprise.context.Dependent
- BeanName=javax.enterprise.inject.spi.Bean,Scope=javax.enterprise.context.Dependent
- BeanName=javax.enterprise.inject.spi.Decorator,Scope=javax.enterprise.context.Dependent
- BeanName=javax.enterprise.inject.spi.Interceptor,Scope=javax.enterprise.context.Dependent
- BeanName=org.hibernate.validator.internal.cdi.ValidationExtension,Scope=javax.enterprise.context.ApplicationScoped
- BeanName=org.hibernate.validator.internal.engine.ValidatorFactoryImpl,Scope=javax.enterprise.context.ApplicationScoped
- BeanName=org.hibernate.validator.internal.engine.ValidatorImpl,Scope=javax.enterprise.context.ApplicationScoped
- BeanName=org.jberet.creation.BatchBeanProducer,Scope=javax.enterprise.context.Dependent
- BeanName=org.jberet.creation.BatchCDIExtension,Scope=javax.enterprise.context.ApplicationScoped
- BeanName=org.jboss.arquillian.protocol.servlet.runner.ServletTestRunner,Scope=javax.enterprise.context.Dependent
- BeanName=org.jboss.arquillian.testenricher.cdi.container.CDIExtension,Scope=javax.enterprise.context.ApplicationScoped
- BeanName=org.jboss.resteasy.cdi.ResteasyCdiExtension,Scope=javax.enterprise.context.ApplicationScoped
- BeanName=org.jboss.weld.bean.builtin.BeanManagerProxy,Scope=javax.enterprise.context.Dependent
- BeanName=org.jboss.weld.bean.builtin.EventMetadataBean,Scope=javax.enterprise.context.Dependent
- BeanName=org.jboss.weld.bean.builtin.InjectionPointBean,Scope=javax.enterprise.context.Dependent
- BeanName=org.jboss.weld.bean.builtin.InstanceImpl,Scope=javax.enterprise.context.Dependent
- BeanName=org.jboss.weld.bean.builtin.ee.HttpServletRequestBean,Scope=javax.enterprise.context.RequestScoped
- BeanName=org.jboss.weld.bean.builtin.ee.HttpSessionBean,Scope=javax.enterprise.context.SessionScoped
- BeanName=org.jboss.weld.bean.builtin.ee.PrincipalBean,Scope=javax.enterprise.context.Dependent
- BeanName=org.jboss.weld.bean.builtin.ee.ServletContextBean,Scope=javax.enterprise.context.RequestScoped
- BeanName=org.jboss.weld.bean.builtin.ee.UserTransactionBean,Scope=javax.enterprise.context.Dependent
- BeanName=org.jboss.weld.context.conversation.ConversationImpl,Scope=javax.enterprise.context.RequestScoped
- BeanName=org.jboss.weld.context.http.HttpSessionDestructionContext,Scope=javax.enterprise.context.Dependent
- BeanName=org.jboss.weld.event.EventImpl,Scope=javax.enterprise.context.Dependent
- BeanName=org.jboss.weld.manager.BeanManagerImpl,Scope=javax.enterprise.context.Dependent
Logger も、EntityManger も管理Beanにない。。。
んーどういう理屈?
- @Deployment
- public static Archive<?> createTestArchive() {
- return ShrinkWrap.create(WebArchive.class, "test.war")
- .addClasses(Resources.class)
- .addAsResource("META-INF/test-persistence.xml", "META-INF/persistence.xml")
- .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
- ;
- }
Arquillian テストクラスをもう一度よく見てみる。
beans.xml は、CDI を有効化するための、デプロイメント記述子。
ん、Resource.class は?ソースを確認。
- /**
- * This class uses CDI to alias Java EE resources, such as the persistence context, to CDI beans
- *
- * <p>
- * Example injection on a managed bean field:
- * </p>
- *
- * <pre>
- * @Inject
- * private EntityManager em;
- * </pre>
- */
- public class Resources {
- // use @SuppressWarnings to tell IDE to ignore warnings about field not being referenced directly
- @SuppressWarnings("unused")
- @Produces
- @PersistenceContext
- private EntityManager em;
- @Produces
- public Logger produceLog(InjectionPoint injectionPoint) {
- return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
- }
- }
おーあった、あった。Logger と EntityManager のファクトリメソッドをもった Resourceクラス(JBoss Tools のプロジェクトで自動生成されたクラス)は、BeanManagerに管理されてたわ。
納得。