Java面向对象系列[v1.0.0][使用反射生成动态代理]

Shaine ·
更新时间:2024-11-13
· 904 次阅读

在Java的java.lang.reflect包里有个Proxy类和一个InvocationHandler接口,通过使用他们可以生成JDK动态代理类或动态代理对象

使用Proxy和InvocationHandler创建动态代理

Proxy提供了用于创建动态代理类和代理对象的静态方法,他也是所有动态代理类的父类,如果在程序中为一个或多个接口动态的生成实现类,就可以使用Proxy来创建动态代理类,如果需要为一个或多个接口动态的创建实例,也可以使用Proxy来创建动态代理实例
Proxy提供了两个方法来创建动态代理类和动态代理实例

static Class getProxyClass(ClassLoader loader, Class…interfaces):创建一个动态代理类所对应的Class对象,该代理类将实现interfaces所指定的多个接口,第一个ClassLoader参数指定生成动态代理类的类加载器 static Object new ProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):直接创建一个动态代理对象,该代理对象的实现类实现了interfaces指定的系列接口,执行代理对象的每个方法时都会被替换执行InvocationHandler对象的invoke方法
即使采用第一个方法生成动态代理类之后,如果程序需要通过该代理类来创建对象,依然需要传入一个InvocationHandler对象,也就是说系统生成的每个代理对象都有一个与之关联的InvocationHandler对象 动态代理类创建动态代理对象

程序中可以采用先生成一个动态代理类,然后通过动态代理类来创建代理对象的方式生成一个动态代理对象

// 创建一个InvocationHandler对象 InvocationHandler handler = new MyInvocationHandler(...); // 使用Proxy生成一个动态代理类proxyClass Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), new Class[]{Foo.class}); // 获取proxyClass类中带一个InvocationHandler参数的构造器 Constructor ctor = proxyClass.getConstructor(new Class[]{InvocationHandler.class}); // 调用ctor的newInstance方法来创建动态实例 Foo f = (Foo)ctor.newInstance(new Object[]{handler});

简化代码

// 创建一个InvocationHandler对象 InvocationHandler handler = new MyInvocationHandler(...); // 使用Proxy直接生成一个动态代理对象 Foo f = (Foo)Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class[]{Foo.class}, handler); 使用Proxy和InvocationHandler生成动态代理对象 import java.lang.reflect.*; interface Person { void walk(); void sayHello(String name); } class MyInvocationHandler implements InvocationHandler { /* 执行动态代理对象的所有方法时,都会被替换成执行如下的invoke方法 其中: proxy:代表动态代理对象 method:代表正在执行的方法 args:代表调用目标方法时传入的实参。 */ public Object invoke(Object proxy, Method method, Object[] args) { System.out.println("----正在执行的方法:" + method); if (args != null) { System.out.println("下面是执行该方法时传入的实参为:"); for (var val : args) { System.out.println(val); } } else { System.out.println("调用该方法没有实参!"); } return null; } } public class ProxyTest { public static void main(String[] args) throws Exception { // 创建一个InvocationHandler对象 InvocationHandler handler = new MyInvocationHandler(); // 使用指定的InvocationHandler来生成一个动态代理对象 var p = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class[] {Person.class}, handler); // 调用动态代理对象的walk()和sayHello()方法 p.walk(); p.sayHello("孙悟空"); } } 动态代理和AOP 开发实际应用的软件系统时,通常会存在相同的代码段重复出现的情况,在这种情况下,往往又会出现的做法是:选中那些代码,一路复制黏贴,立即实现了系统功能,如果仅从实现功能角度来说,确实已经完成了软件开发 再有个升级版本就是通过调用相同的代码实现代码复用,如果需要修改则只需要修改一处的代码多处生效,降低软件后期维护的复杂度

如图所示两种方式:
原创文章 238获赞 273访问量 22万+ 关注 私信 展开阅读全文
作者:Davieyang.D.Y



反射 JAVA 对象 代理 动态代理 动态

需要 登录 后方可回复, 如果你还没有账号请 注册新账号