我使用felix和pax 0.13和焊接。B中有两个包A,在包A中有BundleTracker和定制器,在包B中有CDI。因此,我希望在包跟踪器中使用bean管理器从包B中获取cdi。所以我在定制程序中有这样的方法:
@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容器仍然没有做好准备。如何解决这些问题呢?
发布于 2016-12-27 11:45:44
有时无法找到bean管理器,这是因为CDI容器也是由PAX包中的包侦听器(异步)创建的。这意味着您可能会遇到争用状态,因为在调用包侦听器时可能会创建容器,也可能不会创建容器。
在使用PAX时,我不建议尝试访问bean管理器,而是将所需的bean导出为OSGi服务(@OsgiServiceProvider在bean上的注释),并通过ServiceTracker跟踪该服务。如果由于bean的作用范围,这是不可能的,那么始终可以在容器中创建一个单独的工厂模式bean,用于为您创建bean,并将其作为服务导出。
https://stackoverflow.com/questions/41259197
复制相似问题