0

我使用 felix 和 pax-cdi 0.13 并焊接。我在 B 中有两个包 A。在包 AI 中有 BundleTracker 和 Customizer,在包 BI 中有 CDI bean。所以我想在捆绑跟踪器中使用 bean 管理器从捆绑 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 容器还没有准备好。如何解决这样的问题?

4

1 回答 1

1

有时无法找到 bean 管理器的事实是由于 CDI 容器也是由来自 PAX-CDI 包的包侦听器(异步)创建的。这意味着您可能会遇到竞争条件,因为容器可能会或可能不会在调用捆绑侦听器时创建。

使用 PAX-CDI 时,我不建议尝试访问 bean 管理器,而是将所需的 bean 导出为 OSGi 服务(bean 上的@OsgiServiceProvider 注释)并通过ServiceTracker. 如果由于 bean 的范围而无法做到这一点,您始终可以在容器中创建一个单独的工厂模式 bean,该 bean 为您创建 bean 并将其导出为服务。

于 2016-12-27T11:45:44.743 回答