拦截Java字段和方法访问,创建代理对象(Intercepting Java field and method access, creating proxy objects)

我想在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-like,所以我们称之为Jython),并且非常紧密地考虑Java集成。 其中一个jythonObject.some_attribute设计功能是只需输入jythonObject.some_attribute从Java代码无缝访问Jython对象属性。 所以这里是交易。

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

I want to create such object in Java that will contain some "dispatcher" function like Object getAttr(String name) that will receive all attribute access attempts - so, if I'll do System.out.print(myObj.hello), actual code will be translated to something like System.out.print(myObj.getAttr('hello')), and if I will do myObj.hello = 123, it should execute as myObj.setAttr('hello', 123). Please, note that I should be able to use ANY attribute name, I don't know list of possible names in advance.

So, in this case, is it ever possible?

UPD#1: I'm writing new language for JVM (somehow (J|P)ython-like, so let's call it Jython) with very tight Java integration intented. One of wanted design features is ability to seamlessly access Jython object attributes from Java code just by typing jythonObject.some_attribute. So here is the deal.

Closed: Using AOP via AspectJ seems to be the only possible solution for this, so thank you all for help, and especially Thomas for the most extended answer :)

最满意答案

使用纯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; } }

It is not possible using pure Java, except via:

Bytecode Manipulation

For example using AspectJ.

Annotation Processor

Using a custom annotation processor, which actually is a kind of bytecode manipulation as well. Projekt Lombok is doing something like this.

Synthetic Accessor Method

That is, if the code is anyway using a synthetic accessor method (in which case you could in theory create a proxy):

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; } }拦截Java字段和方法访问,创建代理对象(Intercepting Java field and method access, creating proxy objects)

我想在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-like,所以我们称之为Jython),并且非常紧密地考虑Java集成。 其中一个jythonObject.some_attribute设计功能是只需输入jythonObject.some_attribute从Java代码无缝访问Jython对象属性。 所以这里是交易。

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

I want to create such object in Java that will contain some "dispatcher" function like Object getAttr(String name) that will receive all attribute access attempts - so, if I'll do System.out.print(myObj.hello), actual code will be translated to something like System.out.print(myObj.getAttr('hello')), and if I will do myObj.hello = 123, it should execute as myObj.setAttr('hello', 123). Please, note that I should be able to use ANY attribute name, I don't know list of possible names in advance.

So, in this case, is it ever possible?

UPD#1: I'm writing new language for JVM (somehow (J|P)ython-like, so let's call it Jython) with very tight Java integration intented. One of wanted design features is ability to seamlessly access Jython object attributes from Java code just by typing jythonObject.some_attribute. So here is the deal.

Closed: Using AOP via AspectJ seems to be the only possible solution for this, so thank you all for help, and especially Thomas for the most extended answer :)

最满意答案

使用纯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; } }

It is not possible using pure Java, except via:

Bytecode Manipulation

For example using AspectJ.

Annotation Processor

Using a custom annotation processor, which actually is a kind of bytecode manipulation as well. Projekt Lombok is doing something like this.

Synthetic Accessor Method

That is, if the code is anyway using a synthetic accessor method (in which case you could in theory create a proxy):

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; } }