CDI 如何在没有接口的情况下为 类 注入代理

How CDI injects proxies for classes without interfaces

据我所知,CDI 使用动态代理进行非依赖 bean 注入。如果有一个class实现了一些接口就没有问题,例如:

@SessionScoped
public class MessageBean implements Message {...}

proxy可以基于Message接口创建,但是如果class没有实现接口怎么办:

@SessionScoped
public class MessageBean {...}

注入 Servlet 仍然有效:

@WebServlet("/example")
public class MessageServlet extends HttpServlet {

    @Inject
    private MessageBean messageBean;

所以问题是 Weld 如何处理它?

并非每个代理都是 java.lang.reflect.Proxy 的实例,Weld 在这一点上有自己的代理框架,可以子class 任何非最终 class。 Weld 也不使用 javassist 进行代理(旧版本使用,但 2.x 是内部的)。

如果您想知道它是如何发生的,您可以在这里找到:https://github.com/weld/core/blob/master/impl/src/main/java/org/jboss/weld/bean/proxy/ProxyFactory.java

请注意 - 整个过程依赖于非最终方法和 classes。您会注意到,即使是 CDI 规范也引用了非最终版本。