Java动态代理()

Java动态代理

在学习Spring的时候,对于书上经常讲的动态代理就是一知半解的,学习Spring框架的时候也是囫囵吞枣的
接下来让我来整理一下动态代理的学习思路

首先,什么是动态代理:

 照我的理解就是; A想要调用B,但是它不直接调用B,它利用反射的机制创建了一个C,然后让C调用B,在C这个类调用B之前和之后呢,可以分别实现一些登录验证,打印日志之类的操作,然后再让A调用C,这个时候A即调用了B,且AB的耦合度还降低了,还实现了更多的功能,简直一举两得,好处多多.
 代理类在程序运行时创建的代理方式被称为 动态代理。 也就是说,这种情况下,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。相比于静态代理, 动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类的函数。

接下来我先来创建一个ArrayList的动态代理,熟悉一下代理流程

package cn.ycl.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
public class test4 {
	public static void main(String[] args) {
		// 第一步,创建一个ArrayList对象
		List<String> list = new ArrayList<String>();
		// 第二步,利用Proxy代理类的newProxyInstance方法,生成一个目标代理类
		Object newProxyInstance = Proxy.newProxyInstance(list.getClass().getClassLoader(),
				list.getClass().getInterfaces(), new InvocationHandler() {
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						// TODO Auto-generated method stub
						return method.invoke(list, args);
					}
				});
		// 第三步,利用list的代理类newProxyInstance调用list的方法
		boolean add = ((List<String>) newProxyInstance).add("你好");
		System.out.println(list);
	}
}

结果:
在这里插结果入图片描述

好的,写完这个基本的ArrayList动态代理我感觉自己对代理流程更加清晰了,接下来就来搞一波,复杂一点的,完成前置增强和后置增强吧。
步骤:
①定义一个YCL接口
②定义一个YuanChangLiang类
③定义一个生产代理对象并调用的ProxyYuanChangLiang类

首先第一步,定义一个YCL接口

package cn.ycl.test;
//接口名字是我名字的拼音缩写,6不6?
public interface YCL {
	
void coding();
void playing();
}

第二步,定义一个YuanChangLiang类

package cn.ycl.test;
//这个类就相当于我前面说的 B
public class YuanChangLiang implements YCL{

	@Override
	public void coding() {
		// TODO Auto-generated method stub
		System.out.println("袁昌亮正在敲代码。。。");
	}
	@Override
	public void playing() {
		// TODO Auto-generated method stub
		System.out.println("袁昌亮正在混吃等死。。。");
	}
}

第三步.定义一个生产代理对象并调用的ProxyYuanChangLiang类

package cn.ycl.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//这个类就相当于我前面说的 A
public class ProxyYuanChangLiang {
	public static void main(String[] args) {
//第一步,  按照前面写ArrayList的动态代理的经验,创建被代理类的实例对象
		YuanChangLiang ycl = new YuanChangLiang();
		// 第二步,利用Proxy代理类生成代理对象,这个实例对象就相当于我前面说的 C
		YCL yclProxy = (YCL) Proxy.newProxyInstance(ycl.getClass().getClassLoader(), ycl.getClass().getInterfaces(),
				new InvocationHandler() {
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						// 在方法调用之前就是前置增强啦。。
						if (method.getName().equals("coding")) {
							System.out.println("hello,我是在打代码前面吗?");
							return method.invoke(ycl, args);
						}
						if (method.getName().equals("playing")) {
							// 在方法后面调用就是后置增强啦。。
							Object invoke = method.invoke(ycl, args);
							System.out.println("hello,我是在混吃等死后面吗?");
							return invoke;
						}
						return null;
					}
				});
		// 第三步,利用代理对象调用YuanChangLiang的方法,easy
		yclProxy.coding();
		yclProxy.playing();
	}
}

结果:
在这里插入图片描述

结果可喜,待补充
以上是JDK代理方式,其实动态代理可以分为两种方式,除了JDK代理,还有CGLIB的代理方式,那么两者有什么区别呢。下面是我认为总结的比较好的一张图

在这里插入图片描述

posted @   道祖且长  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示