PAX-CDI: CdiContainerFactory and BundleTracker



我使用felix和pax-cdi 0.13和焊缝。我在B中有两个捆绑。因此,我希望在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。正如我想,当捆绑B变成活动CDI容器时,仍未准备好。如何解决此类问题?

有时找不到bean Manager的事实是因为CDI容器是(异步)由PAX-CDI捆绑包中的捆绑侦听器创建的。这意味着您可能会遇到比赛条件,因为在捆绑侦听器时可能会或可能不会创建容器。

使用PAX-CDI时,我不建议尝试访问Bean Manager,而是建议您作为OSGI服务所需的BEAN(@osgiserviceProvider在BEAN上的注释)并通过ServiceTracker跟踪该服务。如果由于bean的范围而无法实现,您可以随时在容器中创建一个单独的工厂模式bean,使bean创建对您有效并导出该服务。

最新更新