Java: 是否可以在运行时向活动对象实例添加/附加代理?
Java: Is it possible to add / attach a proxy to a live object instance during runtime?
我知道 Java 支持代理。我一直在检查 Javassist 但不确定它是否可以支持以下技巧:
public class Hello {
public void hi() {
System.out.println("hi");
}
}
Hello hello = new Hello();
Hello proxyHello = createProxy(hello);
proxyHello.hi(); // method will be intercepted by a predefined proxy
是否可以这样做?
您可以使用 java.lang.reflect.Proxy
来完成这样的事情。
https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Proxy.html
JDK中可用的只允许创建实现一组接口的代理,如果要创建Class
的代理,则需要使用Javassist
但是为了能够做到这一点,您需要一个可以从创建代理的 class 访问的构造函数。
这里有一个实现你所需要的方法:
final Hello hello = new Hello() {
public void hi() {
System.out.println("Hello World");
}
};
ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(Hello.class);
MethodHandler handler = (self, m, proceed, args) -> {
// This allows to proxy even non accessible methods, it could not be
// needed depending on your context
if (!m.isAccessible())
m.setAccessible(true);
return m.invoke(hello, args);
};
Hello proxy = (Hello)factory.create(new Class<?>[0], new Object[0], handler);
proxy.hi();
输出:
Hello World
在这个例子中:
- 首先我创建我的工厂
- 那我提供超级class
- 然后我定义如何处理代理上的所有方法调用(这里我将所有内容委托给我的活动对象)
- 最后我创建了我的代理(这里我使用默认构造函数来创建代理)。
更多详情here
假设您有一个带有一个 String
参数的构造函数,您需要将最后一行修改为下一行:
Hello proxy = (Hello)factory.create(
new Class<?>[]{String.class}, new Object[]{"bar"}, handler
);
在这里,我使用一个 String
类型的参数调用构造函数,并提供 bar
作为值。
我知道 Java 支持代理。我一直在检查 Javassist 但不确定它是否可以支持以下技巧:
public class Hello {
public void hi() {
System.out.println("hi");
}
}
Hello hello = new Hello();
Hello proxyHello = createProxy(hello);
proxyHello.hi(); // method will be intercepted by a predefined proxy
是否可以这样做?
您可以使用 java.lang.reflect.Proxy
来完成这样的事情。
https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Proxy.html
JDK中可用的只允许创建实现一组接口的代理,如果要创建Class
的代理,则需要使用Javassist
但是为了能够做到这一点,您需要一个可以从创建代理的 class 访问的构造函数。
这里有一个实现你所需要的方法:
final Hello hello = new Hello() {
public void hi() {
System.out.println("Hello World");
}
};
ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(Hello.class);
MethodHandler handler = (self, m, proceed, args) -> {
// This allows to proxy even non accessible methods, it could not be
// needed depending on your context
if (!m.isAccessible())
m.setAccessible(true);
return m.invoke(hello, args);
};
Hello proxy = (Hello)factory.create(new Class<?>[0], new Object[0], handler);
proxy.hi();
输出:
Hello World
在这个例子中:
- 首先我创建我的工厂
- 那我提供超级class
- 然后我定义如何处理代理上的所有方法调用(这里我将所有内容委托给我的活动对象)
- 最后我创建了我的代理(这里我使用默认构造函数来创建代理)。
更多详情here
假设您有一个带有一个 String
参数的构造函数,您需要将最后一行修改为下一行:
Hello proxy = (Hello)factory.create(
new Class<?>[]{String.class}, new Object[]{"bar"}, handler
);
在这里,我使用一个 String
类型的参数调用构造函数,并提供 bar
作为值。