0

felix と pax-cdi 0.13 を使用して溶接します。B に 2 つのバンドル A があります。バンドル AI には BundleTracker とカスタマイザーがあり、バンドル 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 をスローすることがあります。バンドル B がアクティブになると、CDI コンテナーはまだ準備ができていないと思います。そのような問題はどのように解決できますか?

4

1 に答える 1

1

Bean マネージャーが見つからない場合があるのは、CDI コンテナーが PAX-CDI バンドルのバンドル リスナーによって (非同期的に) 作成されるためです。これは、バンドル リスナーが呼び出されたときにコンテナーが作成される場合と作成されない場合があるため、競合状態に陥る可能性があることを意味します。

PAX-CDI を使用する場合、Bean マネージャーにアクセスすることはお勧めしませんが、代わりに、必要な Bean を OSGi サービス (Bean の @OsgiServiceProvider アノテーション) としてエクスポートし、ServiceTracker. Bean のスコープが原因でそれが不可能な場合は、Bean 作成作業を行うコンテナー内に別個のファクトリー・パターン Bean をいつでも作成し、それをサービスとしてエクスポートできます。

于 2016-12-27T11:45:44.743 に答える