具体类的动态代理

17

我希望在Java程序中定义一个方法拦截器,换句话说,我想要一个在每次方法调用时都执行的行为。这个应用程序不在应用服务器中执行,因此我不能使用EJB环绕调用拦截器。 我在标准Java库中找到了一个不错的Proxy API,但它有限制,因为它需要在代理创建时提供一个接口:

 Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                                      new Class[] { Foo.class },
                                      handler);

是否有类似的API,不强制声明Foo.class为接口?

4个回答

6

为什么不使用CGLIB?请参阅this article了解更多信息。

如果您想代理没有接口的旧类,该怎么办? 您可以使用CGLIB。CGLIB是一个强大的高性能代码生成库。在内部,它使用ASM,一个小但快速的字节码操作框架,来转换现有的字节码以生成新类。CGLIB比JDK动态代理方法更快。基本上,它动态生成一个子类来覆盖代理类的非final方法,并连接钩子回调到用户定义的拦截器。


我对CGLIB还不熟悉。我的理解是它会在内存中生成类二进制文件,但现有的类加载器只能从文件系统中加载类,那么它如何使用自己的类加载器呢? - Chao

1

很遗憾,对于类没有这样的API。许多框架使用字节码生成库(如CGLIB)来实现此功能。


1

你可以尝试使用其中一个模拟类。最简单的方法可能是子类化你的类。或者你可以使用AOP来注入你想要的日志记录代码。


0

sun.misc.ProxyGenerator 可用于生成代理类并不检查它们的“接口”是否都是接口。它的 generateClassFile 方法将字节码作为字节数组给出,您可以将其保存以链接到未来的构建或使用第三方工具进行修改。

请注意,如果任何一个“接口”具有 final 方法,则在尝试加载类时会出现错误。


sun.misc.ProxyGenerator 在较新的 Java 版本中不可用。 - cdalxndr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接