转载

java – 为什么CDI bean不支持final方法

我刚刚在GlassFish服务器下发生了臭名昭着的 Java

EE CDI错误:

org.glassfish.deployment.common.DeploymentException: CDI deployment failure:Exception List with 2 exceptions:
Exception 0 :
org.jboss.weld.exceptions.DeploymentException: WELD-001437 Normal scoped bean class ASController is not proxyable because the type is final or it contains a final method public final void ASController.selectPath(org.primefaces.event.NodeSelectEvent) - Managed Bean [class ASController] with qualifiers [@Default @Any @Named].

这个错误非常明显,因为他不喜欢CDI bean中的final方法,但是我无法理解为什么.

在这个链接

http://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html_single/#d0e1429

他们解释说它与序列化有关但我不明白为什么用最终方法序列化一个类应该比使用非最终方法更难.

好吧,有几种方法可以实现代理对象.但是,由于您希望代理与代理bean具有“相同”类型,因此您必须使用继承(或者您可以实现的需求接口,但这不是每个POJO都可以作为bean的方法) CDI).

也就是说,它们在内部从您想要注入的类扩展,生成一些代理代码并为您提供该子类.

然后,这个代理处理所有的魔法,以确保你总是有一个适合你的上下文的bean(这个bean有所有成员变量bean指向恰到好处的bean).

所以你并没有真正收到你想要注入的bean的类型,而是接受那个bean的代理子类.这对最终方法和类以及私有构造函数不起作用.

如果类不是final,则代理可以扩展此类,但是它不能轻易覆盖您的最终方法.然而,这可能是需要的(例如,如果您的bean被序列化,则代理需要对其进行反序列化).

围绕这一点,有更复杂的方法.可以通过代理操作类的字节代码来注入此功能(例如删除最终修饰符,注入默认构造函数,……)甚至可以将它与继承混合使用,但这只是没有实现,但是(和同样非常容易支持多个JVM实现).

从链接的资源中,注释表明此计划用于将来的版本:

Note
A future release of Weld will likely support a non-standard workaround  for this limitation, using non-portable JVM APIs:  Sun, IcedTea, Mac: Unsafe.allocateInstance() (The most efficient)  IBM, JRockit: ReflectionFactory.newConstructorForSerialization() 
But we didn’t get around to implementing this yet.

翻译自:https://stackoverflow.com/questions/20681981/why-cdi-beans-dont-support-final-methods

原文  https://codeday.me/bug/20190112/518171.html
正文到此结束
Loading...