我有一个CDI bean,并且将拦截器添加到该bean的一种方法中。
如果此bean没有默认构造函数(我使用构造函数注入(inject))。
在运行时,出现异常
java.lang.Class.newInstance0(Class.java:357)
java.lang.Class.newInstance(Class.java:325)
org.apache.webbeans.proxy.javassist.JavassistFactory.createProxy(JavassistFactory.java:79)
org.apache.webbeans.proxy.ProxyFactory.createProxy(ProxyFactory.java:241)
org.apache.webbeans.proxy.ProxyFactory.createDependentScopedBeanProxy(ProxyFactory.java:412)
org.apache.webbeans.component.AbstractInjectionTargetBean.createDefaultInstance(AbstractInjectionTargetBean.java:140)
org.apache.webbeans.component.AbstractInjectionTargetBean.createInstance(AbstractInjectionTargetBean.java:116)
org.apache.webbeans.component.AbstractOwbBean.createNewInstance(AbstractOwbBean.java:233)
org.apache.webbeans.portable.creation.AbstractProducer.produce(AbstractProducer.java:77)
org.apache.webbeans.component.InjectionTargetWrapper.produce(InjectionTargetWrapper.java:136)
如果我在此bean中添加默认构造函数,或删除拦截器,那就可以了。
实际上,我可以使用场注入(inject)来解决这个问题。
但我想知道:如果添加默认构造函数,则意味着此bean有两个构造函数-一个是非参数构造函数,另一个是
@Inject
ed参数。在这种情况下(使用拦截器),容器将两次创建实例吗?编辑:我使用Tomee1.5,而WebShpere8.5与Tomee1.5相同
并且似乎GlassFish3.1.2没有此问题。
编辑:我在Tomee用户论坛中找到了一个答案,即
CDI容器将为您的bean调用@Inject注释的ct,但将使用默认的ct创建代理。
因此,我认为这意味着如果要使用构造函数注入(inject),则还需要一个默认的构造函数才能实现代理。
编辑:
除非bean具有默认范围@Dependent,否则容器必须通过代理对象间接调用所有注入(inject)到bean的引用。
CDI容器将为您的bean调用@Inject注释的构造函数,但将使用默认的构造函数创建代理。因此,所有“NormalScoped”(@ RequestScoped @SessionScoped @ApplicationScoped @ConversationScoped)Bean都需要默认构造函数,因为它们将始终被代理。
因此,如果我使用Tomee和Websphere,则需要一个默认ct,而GlassFish则不需要。
谢谢brandizzi,这是我的第一个问题。感谢您的帮助。
而且似乎我无法回答自己的问题并发布两个以上的链接
没有10个声誉,所以我在这里进行了编辑。
最佳答案
如CDI specification中所述,具有绑定(bind)拦截器的CDI bean必须是可代理的(如unproxyable bean types所定义),该声明还声明proxyblebean是具有无参数的非 private 构造函数的类。
关于default - 具有拦截器的CDI bean是否应具有默认构造函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15637391/