我使用felix和pax-cdi 0.13并焊接。我在B中有两个捆绑A.在捆绑A中我有BundleTracker和Customizer,在捆绑B中我有CDI bean。所以我想在bundle tracker中使用bean manager从bundle B中获取cdi bean。所以我在定制器中有方法:
@Override
public Object addingBundle(Bundle bundle, BundleEvent event) {
String marker = (String) bundle.getHeaders().get("Some-Marker");
if (marker != null) {
try {
//1 we get CdiContainerFactory
BundleContext thisBundleContext=FrameworkUtil.getBundle(this.getClass()).getBundleContext();
ServiceReference<?> sr = thisBundleContext.getServiceReference(CdiContainerFactory.class.getName());
CdiContainerFactory cdiContainerFactory = (CdiContainerFactory) thisBundleContext.getService(sr);
if (cdiContainerFactory==null){
System.out.println("Cdi container factory is null");
}else{
System.out.println("Cdi container factory is not null");
}
//2 we get BeanManager from CdiContainerFactory
Class<?> klass = bundle.loadClass("com.temp.Temp");
BeanManager beanManager = cdiContainerFactory.getContainer(bundle).getBeanManager();
Bean<?> bean = (Bean<?>)beanManager.resolve(beanManager.getBeans(klass));
Object temp= beanManager.getReference(bean, bean.getBeanClass(), beanManager.createCreationalContext(bean));
} catch (ClassNotFoundException ex) {
Logger.getLogger(ExtenderBundleTracker.class.getName()).log(Level.SEVERE, null, ex);
}
}
return bundle;
}
要注册捆绑包跟踪器,请使用以下代码:
bundleTracker=new BundleTracker<>(context, Bundle.ACTIVE, new MyCustomizer());
上面的代码有效。但不总是。我有计时问题。我总是得到Cdi container factory is not null
,但是接下来的行
BeanManager beanManager = cdiContainerFactory.getContainer(bundle).getBeanManager();
有时会抛出NullPointerException。 正如我想的那样,当Bundle B变为活动状态时,CDI容器仍未准备就绪。如何解决这个问题?
答案 0 :(得分:1)
有时无法找到bean管理器的事实是由于CDI容器(也是异步)由来自PAX-CDI bundle的bundle侦听器创建的。这意味着您可能会遇到竞争条件,因为在调用捆绑侦听器时可能会创建容器,也可能不会创建容器。
使用PAX-CDI时,我不建议尝试访问bean管理器,而是将您需要的bean作为OSGi服务(bean上的@OsgiServiceProvider注释)导出,并通过{{1}跟踪该服务}。如果由于bean的范围而无法实现,那么您始终可以在容器中创建一个单独的工厂模式bean,为您创建bean并将其作为服务导出。