[英]How to ensure a Java CDI framework implementation will inject an instance at a custom injectionpoint of a custom bean?
鑒於:
如何確保 CDI 將注入 InjectionPoint 所需類型的實例?
換句話說,我如何為我無法控制的 class 構造一個自定義 bean,這樣我仍然可以將我可以控制的 class 的實例注入到特定字段中?
我當前的(非功能性)代碼如下所示:
void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager beanManager) {
final AnnotatedType<ClassWithoutControl> annotatedType = beanManager.createAnnotatedType(ClassWithoutControl.class);
AnnotatedField<ClassWithoutControl> annotatedField = null;
for (AnnotatedField<? super ClassWithoutControl> field : annotatedType.getFields()) {
if ("field".equals(field.getJavaMember().getName()) && ClassWithControl.class.equals(field.getJavaMember().getType())) {
annotatedField = (AnnotatedField<ClassWithoutControl>) field;
break;
}
}
final InjectionPoint injectionPoint = beanManager.createInjectionPoint(annotatedField);
final HashSet<InjectionPoint> injectionPoints = new HashSet<>();
injectionPoints.add(injectionPoint);
BiFunction<CreationalContext<ClassWithoutControl>, Bean<ClassWithoutControl>, ClassWithoutControl> creator = (creationalContext, bean) -> {
final InjectionTarget<ClassWithoutControl> injectionTarget = beanManager.createInjectionTarget(annotatedType);
ClassWithoutControl instance = new ClassWithoutControl(this.paramater1, this.parameter2);
injectionTarget.inject(instance, creationalContext);
injectionTarget.postConstruct(instance);
return instance;
};
customBeanBuilder.setInjectionPoints(injectionPoints).setCreator(creator);
final BeanAttributes<ClassWithoutControl> beanAttributes = beanManager.createBeanAttributes(annotatedType);
customBeanBuilder.setBeanAttributes(beanAttributes);
abd.addBean(customBeanBuilder.build());
}
CustomBeanBuilder 是一個 class ,它創建一個擴展 Bean 的 CustomBean 實例。 創建者 BiFunction 在 CustomBean 的 create(CreationalContext ctx) function 中被調用。 創建者的參數是傳遞給 create() 的 CreationalContext 和 CustomBean (this)。
我知道為什么上述方法不起作用。 Weld 返回 NonProducibleInjectionTarget,因為 Weld 用於創建 InjectionTarget 的 AnnotatedType 沒有無參數構造函數。 然而,我正在尋找一種方法可以做到這一點,而不必依賴 Weld 的內部實現。 在重新訓練注入另一個實例的能力時,我找不到一種方法來欺騙 CDI 接受我的 ClassWithoutControl 實例。
我看過https://docs.jboss.org/weld/reference/latest/en-US/html_single/#_wrapping_an_injectiontarget但我不太明白如何創建這樣的包裝器。 因此,我們也將不勝感激這方面的任何幫助。
我深入研究 Weld(我當前的 CDI 實現),看看我是否能找到解決這個問題的方法。 不幸的是,由於我無法控制的 class 中缺少無參數構造函數,我無法提供 InjectionTarget。 BeforeBeanDiscovery 顯示擴展正在添加 class 的 bean。 然而,由於它缺少無參數構造函數,因此永遠不會創建 InjectionTarget。
我試圖通過在 ProcessAnnotatedType 期間包裝 AnnotatedType 並插入 AnnotatedConstructor 並將其與原始 AnnotatedType 的構造函數一起返回來解決此問題。 這可以做到,不幸的是 AnnotatedConstructor 有一個 getJavaMember() 方法,它返回原始構造函數。 在我的情況下,構造函數(java-member)不存在並且看到你無法實例化構造函數的新實例。 這是一個死胡同,因為沒有其他方法可以獲取構造函數的自定義實例。
我現在正在探索字節碼操作庫,例如 byte-buddy。 這些將使我能夠在運行時添加一個無參數構造函數。 對我沒有任何影響,因為無參數構造函數的唯一目的是確保 CDI 將 class 標記為有效 Bean。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.