Java EE 7 検証環境構築(5) JBoss Toolsが生成したサンプルソースのCDIを確認する

  1. Java EE 7 検証環境構築(1) WildFly + JBoss Tools で EARプロジェクトを作成し Arquillian で ユニットテストをグリーンにするところまで
  2. Java EE 7 検証環境構築(2) WildFly に DataSourceを作成
  3. Java EE 7 検証環境構築(3) JPAからMySQLに接続するユニットテストをArquillianで実行
  4. Java EE 7 検証環境構築(4) Java EE での DI(Dependency Injection) および CDI(Contexts and Dependency Injection)をながめる
  5. Java EE 7 検証環境構築(5) JBoss Toolsが生成したサンプルソースのCDIを確認する
  6. Java EE 7 検証環境構築(6) JPA エンティティの作成と挿入
  7. Java EE 7 検証環境構築(7) JPA 問い合わせ(1) 名前付きクエリを使ってみる。テストでトランザクションも意識する
  8. Java EE 7 検証環境構築(8) JPA 問い合わせ(2) 動的クエリとCriteria API を試す
  9. Java EE 7 検証環境構築(9) jBatch 概要をおさえる
  10. Java EE 7 検証環境構築(10) JBoss Tools で作成した EARプロジェクトをJava EE 6 から 7 に変更する
  11. Java EE 7 検証環境構築(11) jBatch用 プロジェクトの作成を行う
  12. Java EE 7 検証環境構築(12) jBatch 簡易サンプル作成と Arquillian でユニットテスト
  13. Java EE 7 検証環境構築(13) jBatch REST サービス経由で実行する
  14. Java EE 7 検証環境構築(14) WildFly の管理をGUIで行う
  15. Java EE 7 検証環境構築(15) WildFly を サービスとして設定する(Windows/Linux)
  16. Java EE 7 検証環境構築(16) WildFly と Apache を mod_jk で連携させる(Widows)

CDI の参照実装 JBoss Weld

CDI の概要は何となく理解した。後は、どう使うのか。

まず、JBoss Tools で自動作成された EAR Project のサービスクラスを確認してみる。

  1. @Stateless
  2. public class MemberRegistration {
  3.  
  4. @Inject
  5. private Logger log;
  6.  
  7. @Inject
  8. private EntityManager em;
  9.  
  10. @Inject
  11. private Event memberEventSrc;
  12. public void register(Member member) throws Exception {
  13. log.info("Registering " + member.getName());
  14. em.persist(member);
  15. memberEventSrc.fire(member);
  16. }
  17. }

さて、ここでインジェクトされている、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の一覧を確認してみる。

BeanManager

Any bean may obtain an instance of BeanManager by injecting it:

 @Inject
 BeanManager manager;

Arquillian テストケースで、BeanManager が管理しているBean一覧を出力

  1. @RunWith(Arquillian.class)
  2. public class BeanManagerTest {
  3. @Deployment
  4. public static Archive<?> createTestArchive() {
  5. return ShrinkWrap.create(WebArchive.class, "test.war")
  6. .addClasses(Resources.class)
  7. .addAsResource("META-INF/test-persistence.xml", "META-INF/persistence.xml")
  8. .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
  9. ;
  10. }
  11.  
  12. @Inject
  13. Logger log;
  14. @Inject
  15. BeanManager manager;
  16. @Test
  17. public void testListAllBeans() throws Exception {
  18. @SuppressWarnings("serial")
  19. Set<?>> beans = manager.getBeans(Object.class, new AnnotationLiteral(){});
  20. for (Bean<?> bean: beans) {
  21. log.info(String.format(
  22. "BeanName=%s,Scope=%s",
  23. bean.getBeanClass().getName(),
  24. bean.getScope().getName()));
  25. }
  26. }
  27. }

結果(Sort & Unique 済み)。

  1. BeanName=com.sun.faces.application.view.ViewScopeExtension,Scope=javax.enterprise.context.ApplicationScoped
  2. BeanName=com.sun.faces.application.view.ViewScopedCDIEventFireHelperImpl,Scope=javax.enterprise.context.Dependent
  3. BeanName=com.sun.faces.flow.FlowCDIEventFireHelperImpl,Scope=javax.enterprise.context.Dependent
  4. BeanName=com.sun.faces.flow.FlowCDIExtension,Scope=javax.enterprise.context.ApplicationScoped
  5. BeanName=com.sun.faces.flow.FlowDiscoveryCDIExtension,Scope=javax.enterprise.context.ApplicationScoped
  6. BeanName=com.sun.faces.flow.FlowDiscoveryCDIHelper,Scope=javax.enterprise.context.Dependent
  7. BeanName=info.typea.tallarico.test.BeanManagerTest,Scope=javax.enterprise.context.Dependent
  8. BeanName=info.typea.tallarico.util.Resources,Scope=javax.enterprise.context.Dependent
  9. BeanName=javax.enterprise.inject.spi.Bean,Scope=javax.enterprise.context.Dependent
  10. BeanName=javax.enterprise.inject.spi.Decorator,Scope=javax.enterprise.context.Dependent
  11. BeanName=javax.enterprise.inject.spi.Interceptor,Scope=javax.enterprise.context.Dependent
  12. BeanName=org.hibernate.validator.internal.cdi.ValidationExtension,Scope=javax.enterprise.context.ApplicationScoped
  13. BeanName=org.hibernate.validator.internal.engine.ValidatorFactoryImpl,Scope=javax.enterprise.context.ApplicationScoped
  14. BeanName=org.hibernate.validator.internal.engine.ValidatorImpl,Scope=javax.enterprise.context.ApplicationScoped
  15. BeanName=org.jberet.creation.BatchBeanProducer,Scope=javax.enterprise.context.Dependent
  16. BeanName=org.jberet.creation.BatchCDIExtension,Scope=javax.enterprise.context.ApplicationScoped
  17. BeanName=org.jboss.arquillian.protocol.servlet.runner.ServletTestRunner,Scope=javax.enterprise.context.Dependent
  18. BeanName=org.jboss.arquillian.testenricher.cdi.container.CDIExtension,Scope=javax.enterprise.context.ApplicationScoped
  19. BeanName=org.jboss.resteasy.cdi.ResteasyCdiExtension,Scope=javax.enterprise.context.ApplicationScoped
  20. BeanName=org.jboss.weld.bean.builtin.BeanManagerProxy,Scope=javax.enterprise.context.Dependent
  21. BeanName=org.jboss.weld.bean.builtin.EventMetadataBean,Scope=javax.enterprise.context.Dependent
  22. BeanName=org.jboss.weld.bean.builtin.InjectionPointBean,Scope=javax.enterprise.context.Dependent
  23. BeanName=org.jboss.weld.bean.builtin.InstanceImpl,Scope=javax.enterprise.context.Dependent
  24. BeanName=org.jboss.weld.bean.builtin.ee.HttpServletRequestBean,Scope=javax.enterprise.context.RequestScoped
  25. BeanName=org.jboss.weld.bean.builtin.ee.HttpSessionBean,Scope=javax.enterprise.context.SessionScoped
  26. BeanName=org.jboss.weld.bean.builtin.ee.PrincipalBean,Scope=javax.enterprise.context.Dependent
  27. BeanName=org.jboss.weld.bean.builtin.ee.ServletContextBean,Scope=javax.enterprise.context.RequestScoped
  28. BeanName=org.jboss.weld.bean.builtin.ee.UserTransactionBean,Scope=javax.enterprise.context.Dependent
  29. BeanName=org.jboss.weld.context.conversation.ConversationImpl,Scope=javax.enterprise.context.RequestScoped
  30. BeanName=org.jboss.weld.context.http.HttpSessionDestructionContext,Scope=javax.enterprise.context.Dependent
  31. BeanName=org.jboss.weld.event.EventImpl,Scope=javax.enterprise.context.Dependent
  32. BeanName=org.jboss.weld.manager.BeanManagerImpl,Scope=javax.enterprise.context.Dependent

Logger も、EntityManger も管理Beanにない。。。

んーどういう理屈?

  1. @Deployment
  2. public static Archive<?> createTestArchive() {
  3. return ShrinkWrap.create(WebArchive.class, "test.war")
  4. .addClasses(Resources.class)
  5. .addAsResource("META-INF/test-persistence.xml", "META-INF/persistence.xml")
  6. .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
  7. ;
  8. }

Arquillian テストクラスをもう一度よく見てみる。

beans.xml は、CDI を有効化するための、デプロイメント記述子。

ん、Resource.class は?ソースを確認。

  1. /**
  2. * This class uses CDI to alias Java EE resources, such as the persistence context, to CDI beans
  3. *
  4. * <p>
  5. * Example injection on a managed bean field:
  6. * </p>
  7. *
  8. * <pre>
  9. * @Inject
  10. * private EntityManager em;
  11. * </pre>
  12. */
  13. public class Resources {
  14. // use @SuppressWarnings to tell IDE to ignore warnings about field not being referenced directly
  15. @SuppressWarnings("unused")
  16. @Produces
  17. @PersistenceContext
  18. private EntityManager em;
  19.  
  20. @Produces
  21. public Logger produceLog(InjectionPoint injectionPoint) {
  22. return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
  23. }
  24. }

おーあった、あった。Logger と EntityManager のファクトリメソッドをもった Resourceクラス(JBoss Tools のプロジェクトで自動生成されたクラス)は、BeanManagerに管理されてたわ。

納得。

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です