2017-09-14 139 views
0

在试验Wild-群体的过程中,我遇到了有关豆注射的奇怪情况。野蝇和野蝇群注入CDI豆从战争部署VS定制模块

我有一个非常简单的bean,或多或少是这样的:

@ApplicationScoped 
public class FooServiceImpl implements FooService { 
    Foo delegate; 
    @PostConstruct public void init() { 
     delegate = .....; 
    } 

    public Foo getFoo() { 
     return delegate; 
    } 
} 

如果我在一个罐子里,直接在战争部署捆绑这一点,一切工作正常,并符合市场预期。但是,我需要将此实现的内部部分与应用程序完全隔离,为什么我将服务API及其实现打包到单独的jboss模块中。

这些模块被添加到swarm uberJar中,我的应用依靠它们通过MANIFEST Dependencies条目。现在,一切似乎都很顺利,FooService bean被注入到我的应用程序servlet/rest资源中,但init()方法未被调用。

我无法弄清楚这里发生了什么。这就像bean解析过程无法识别@ApplicationScope注释。可以有两个不同的类加载器吗?

UPDATE

我启用的跟踪,对我,它看起来像焊缝处理FooImpl类作为ApplicationScoped,即增加一个LifecycleMixin.lifecycle_mixin_$$_postConstruct()到代理创建:

2017-09-14 23:11:34,315 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001538: Created context instance for bean Managed Bean [class com.xxx.FooImpl] with qualifiers [@Any @Default] identified as WELD%ManagedBean%test.war|test.war.external.file:/tmp/nestedjarloader2449602760983533131.tmp/META-INF/beans.xml|com.xxx.FooImpl|null|false 
2017-09-14 23:11:34,315 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001542: Retrieving/generating proxy class com.xxx.FooImpl$Proxy$_$$_WeldClientProxy 
2017-09-14 23:11:34,315 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001541: Adding method to proxy: public void com.xxx.FooImpl.registerMessageHandler(com.xxx.MessageHandler) 
2017-09-14 23:11:34,315 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001541: Adding method to proxy: public void com.xxx.FooImpl.registerListeners(java.util.EventListener[]) 
2017-09-14 23:11:34,316 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001541: Adding method to proxy: public void com.xxx.FooImpl.send(com.xxx.MessageHandler,com.xxx.Message) throws java.io.IOException 
2017-09-14 23:11:34,316 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001541: Adding method to proxy: public void com.xxx.FooImpl.init() 
2017-09-14 23:11:34,316 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001541: Adding method to proxy: public java.lang.String java.lang.Object.toString() 
2017-09-14 23:11:34,316 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001541: Adding method to proxy: public abstract void org.jboss.weld.interceptor.proxy.LifecycleMixin.lifecycle_mixin_$$_postConstruct() 
2017-09-14 23:11:34,316 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001541: Adding method to proxy: public abstract void org.jboss.weld.interceptor.proxy.LifecycleMixin.lifecycle_mixin_$$_preDestroy() 
2017-09-14 23:11:34,317 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001543: Created Proxy class of type class com.xxx.FooImpl$Proxy$_$$_WeldClientProxy supporting interfaces [interface com.xxx.FooService, interface java.io.Serializable, interface org.jboss.weld.interceptor.proxy.LifecycleMixin, interface org.jboss.weld.interceptor.util.proxy.TargetInstanceProxy, interface org.jboss.weld.bean.proxy.ProxyObject] 
2017-09-14 23:11:34,317 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001506: Created new client proxy of type class com.xxx.FooImpl$Proxy$_$$_WeldClientProxy for bean Managed Bean [class com.xxx.FooImpl] with qualifiers [@Any @Default] with ID WELD%ManagedBean%test.war|test.war.external.file:/tmp/nestedjarloader2449602760983533131.tmp/META-INF/beans.xml|com.xxx.FooImpl|null|false 
2017-09-14 23:11:34,318 TRACE [org.jboss.weld.Bean] (ServerService Thread Pool -- 12) WELD-001507: Located client proxy of type class com.xxx.FooImpl$Proxy$_$$_WeldClientProxy for bean Managed Bean [class com.xxx.FooImpl] with qualifiers [@Any @Default] 

的postconstruct拦截ISN没有被调用 - 为什么?神秘加深!

UPDATE 2

上香草测试此wildfly,并且行为是相同的,@PostConstruct方法,如果豆位于模块不被调用。

+0

如果你已经在单独的JBoss模块中获得了API和Impl,那么它们确实在单独的类加载器中。 MANIFEST中的impl的module.xml是否确定它应该“导入”WAR类加载器? – Ken

+0

@Ken不,不是,但应该吗?我的意思是,我想在自己的类加载器中使用impl,ApplicationScoped应该只来自一个类加载器。 –

回答

0

我想这个问题,the one in JBoss forums有联系,但如果他们不...

可能的原因是:你的独立模块不声明对<module name="javax.annotation.api"/>这也正是@PostConstruct来自依赖性。加上它,应该解决麻烦。 这似乎是JVM的行为(as explained in this SO question) - 如果您在运行时错过了依赖关系,程序仍然会执行但忽略注释。作为一种解决方法(如果上述不起作用或者你不能这样做) - 你可以使用初始化方法。这是CDI创建对象后立即执行的方法。

+0

他们确实联系在一起:) –