拦截Java字段和方法访问,创建代理对象

时间:2011-06-06 15:24:35

标签: java attributes proxy introspection intercept

我想在Java中创建这样的对象,它将包含一些“调度程序”函数,如Object getAttr(String name),它将接收所有属性访问尝试 - 所以,如果我做System.out.print(myObj.hello),实际代码将是翻译为类似System.out.print(myObj.getAttr('hello'))的内容,如果我执行myObj.hello = 123,则应执行myObj.setAttr('hello', 123)。请注意,我应该能够使用任何属性名称,我不知道可能的名字列表。

那么,在这种情况下,它有可能吗?

UPD#1:我正在为JVM编写新语言(不知怎的(J | P)类似于ython,所以我们称之为Jython)非常紧密的Java集成。其中一个有用的设计功能是只需键入jythonObject.some_attribute即可从Java代码无缝访问Jython对象属性。所以这是交易。

已关闭:通过AspectJ使用AOP似乎是唯一可行的解​​决方案,所以非常感谢大家的帮助,尤其是托马斯最广泛的答案:)

5 个答案:

答案 0 :(得分:3)

使用纯Java是不可能的,除非通过:

字节码操作

例如使用AspectJ。

注释处理器

使用自定义注释处理器,它实际上也是一种字节码操作。 Projekt Lombok正在做这样的事情。

合成访问者方法

也就是说,如果代码无论如何都使用合成访问器方法(在这种情况下,理论上你可以创建一个代理):

public class Test {
    public static void main(String... args) {
        TestClass t = new TestClass();
        // this is actually calling a synthetic accessor method
        t.hello = "x";
    }
    static class TestClass {
        private String hello;
    }
}

答案 1 :(得分:2)

如果我们严格遵守OOP理由,您的田地根本不应该从外面进入。所有字段访问都应该通过get / set方法完成。

通过dynamic proxies可以拦截界面的方法。 (重要提示:您不能使用类,只能使用接口。)

如果这不符合您的需求(虽然除非您正在编写第三方工具,但它可能应该这样),那么只有乱码的方式,面向方面的编程或直接的字节码黑客攻击。

如果我们知道你需要做什么,这会有所帮助。

答案 2 :(得分:1)

您必须使用AspectJ(http://www.eclipse.org/aspectj/)或其他AOP库。

答案 3 :(得分:0)

答案 4 :(得分:0)

Groovy语言有AOP工具, 并且已存在用于处理案例的小型库:https://github.com/nanonull/bean-trace