我目前正在将一个JBoss服务类从AS5.1迁移到AS6 (出于各种原因,我不打算迁移到AS7 )。
对于AS5.1,该服务实现了{serviceName}MBean,并具有带有属性值的jboss-service.xml。它被打包在一个jboss-sar中,它被打包在一个EAR中进行部署。部署后,将使用jboss-service.xml中的值填充服务字段,并且服务将自动注册到JMX中。
我想用AS6来实现同样的事情,但是我希望这个服务支持CDI --所以我希望它的新的@Inject注入点能被满足。我需要在注册到JMX的对象中满足这些要求,以便通过JMX调用的方法可以引用注入的字段,但我正在努力实现这一点。
由于类加载器的原因,我不得不将服务打包在jar中,而不是jboss-sar中,但假设它在其他方面没有变化。当部署到AS6时,一切都像以前一样工作-服务进入JMX,XML值传播到对象。但是,创建的实例不满足其CDI注入点,在JMX中注册的对象也不满足。
如果我用@Startup和@javax.ejb.Singleton注释服务类,但保留它的接口和jboss-service.xml,那么注册到JMX中的对象仍然没有满足它的CDI注入点。但是,如果我以编程方式取消注册该bean,并在@PostConstruct方法中重新注册该实例,那么JMX中的bean确实满足了其注入点。但是,该bean不再具有jboss-service.xml中指定的值。
那么我如何才能两全其美呢?CDI和通常的JBoss服务行为?使用CDI实现JBoss服务的正确方式是什么?我一直找不到关于这方面的文档。希望有人能帮上忙。
谢谢,
本
发布于 2011-07-20 21:45:33
正如在上面的评论中提到的,看起来汤姆是对的--没有什么好的方法可以一次性创建一个CDIed,JMX bean,你要么像上面建议的那样把你的JMX bean放到CDI中,要么把你的CDIed bean放到JMX中。我们尝试了前者,但似乎在服务启动时BeanManager并没有绑定到JNDI。
因此,我们转而使用CDI bean -> JMX。我们将服务创建为单例EJB,因此它们的注入点得到了满足,然后它们在PostConstruct/PreDestroy方法中注册/注销到JMX,使用德国Escobar优秀的CDI可移植扩展线程Community.jboss.org/ (germanescobar.net/2010/01/cdi-portable-extension-jmx.html,/148750也很有帮助)。
可能会尝试使用ApplicationScoped beans,并通过观察ContainerInitialized(?)事件,因为我们不需要EJB的所有功能。我还没试过呢,注意...
发布于 2011-07-17 19:55:12
作为最坏的退路,您应该能够使用CDI extension API来注入您的服务。我不认为你需要写一个完全成熟的扩展,但是如果你在服务对象中有一个初始化钩子,你可以这样做(从文档中略微编辑就可以解除,而不是编译或测试):
public static <T> void inject(T object) {
BeanManager beanManager = (BeanManager)new InitialContext().lookup("java:comp/BeanManager");
AnnotatedType<T> type = beanManager.createAnnotatedType(object.getClass());
InjectionTarget<T> it = beanManager.createInjectionTarget(type);
CreationalContext ctx = beanManager.createCreationalContext(null);
it.inject(object, ctx);
it.postConstruct(object);
}基本上,该方法的任何对象都将被注入。所有常见的CDI注释都应该可以工作。但愿能去。
https://stackoverflow.com/questions/6723260
复制相似问题