2013-07-03 97 views
1

我的問題 - 有誰知道如何獲得Deployment接口的實例Weld?理想情況下beforeBeanDiscovery事件?在JBoss AS 7.1中從動態加載的jar中發現bean

我正試圖在我的應用程序加載jar的應用程序中實現插件系統。我使用的是JBoss AS 7.1

我試圖在部署過程中包含JAR,但似乎不可能,除非該jar在WEB-INF/lib文件夾中。

所以我的下一步就是要讓CDI(Weld)發現外部JAR中的bean。

似乎CDI沒有直接的支持,包括新的罐子被發現,但焊縫具有展開接口和一個叫loadDeploymentArchive(http://docs.jboss.org/weld/javadoc/2.0/weld-spi/org/jboss/weld/bootstrap/spi/Deployment.html#loadBeanDeploymentArchive(java.lang.Class)

回答

0

那類是與應用服務器的集成方法。 CDI是爲了在應用程序啓動時加載一切。要做你正在尋找的東西,你必須啓動一個新的Weld實例,並將所有事情都傳遞給自己,然後進行引導。老實說,我不知道在你的應用程序中這樣做的意義,但我可以告訴你,這會給你帶來很大的麻煩。

0

其實我發現這篇文章從加文·金在回答在http://relation.to/12981.lace

基本上我要創建一個擴展和映射這樣的afterBeanDiscovery事件:

public void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager bm) { 
    for (final Class c: getBeanClasses()) { 

     //use this to read annotations of the class 
     AnnotatedType at = bm.createAnnotatedType(c); 

     //use this to create the class and inject dependencies 
     final InjectionTarget it = bm.createInjectionTarget(at); 

     abd.addBean(new Bean() { 
      @Override 
      public Class<?> getBeanClass() { 
       return c; 
      } 

      @Override 
      public Set<InjectionPoint> getInjectionPoints() { 
       return it.getInjectionPoints(); 
      } 

      @Override 
      public String getName() { 
       String s = c.getSimpleName(); 
       s = Character.toLowerCase(s.charAt(0)) + s.substring(1); 
       return s; 
      } 

      @Override 
      public Set<Annotation> getQualifiers() { 
       Set<Annotation> qualifiers = new HashSet<Annotation>(); 
       qualifiers.add(new AnnotationLiteral<Default>() {}); 
       qualifiers.add(new AnnotationLiteral<Any>() {}); 
       return qualifiers; 
      } 

      @Override 
      public Class<? extends Annotation> getScope() { 
       return Dependent.class; 
      } 

      @Override 
      public Set<Class<? extends Annotation>> getStereotypes() { 
       return Collections.emptySet(); 
      } 

      @Override 
      public Set<Type> getTypes() { 
       Set<Type> types = new HashSet<Type>(); 
       types.add(c); 
       types.add(Object.class); 
       return types; 
      } 

      @Override 
      public boolean isAlternative() { 
       return false; 
      } 

      @Override 
      public boolean isNullable() { 
       return false; 
      } 

      @Override 
      public Object create(CreationalContext ctx) { 
       Object instance = it.produce(ctx); 
       it.inject(instance, ctx); 
       it.postConstruct(instance); 
       return instance; 
      } 

      @Override 
      public void destroy(Object instance, CreationalContext ctx) { 
       it.preDestroy(instance); 
       it.dispose(instance); 
       ctx.release(); 
      } 

     }); 
    } 
} 

我也有掃描我的罐子bean類,但這不是什麼大問題。一旦找到這些類,我將它包含在getBeanClasses()列表中。

現在我正在尋找關於如何在運行時包含JPA實體的解決方案。

但現在這個問題解決了。