前言:动态代理是一种设计模式。之所以学习动态代理这种设计模式,是因为后面学习一些技术、项目中,会用到动态代理。
一、程序为什么需要代理?代理长什么样?
1、为什么需要代理?
拿现实举例:
一个明星,一开始想唱歌就唱歌、想跳舞就跳舞。
等到这个明星稍微有了点热度,就要开始收费表演了,此时单子不多,自己进行准备工作就行。
过了一段时间,这个明星大火,全国各地都邀请她去唱歌、跳舞,单子太多了,于是不得不找一个中介公司,中介公司给她配了一个经纪人(代理),来帮她完成准备工作(准备场地、收钱),而这个明星只负责唱歌、跳舞。
问题1:中介公司是如何知道,要给这个明星配一个有唱歌、跳舞业务的经纪人(代理)呢?
答案:通过自己定义的接口。
问题2:经纪人(代理)的方法中,具体唱歌、跳舞的动作是谁执行的?
答案:经纪人(代理)只负责准备工作、收钱,而具体的唱歌、跳舞的动作,还是会叫这个明星来执行。
2、如何为Java对象创建一个代理对象?
3、举例:
①编写接口(中介公司为明星配经纪人的依据)
②编写明星类
③编写生成代理对象的工具类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//代理工具类:用于给对象生成代理对象(现实中:中介公司)
public class ProxyUtil {
//创建一个明星对象的代理对象,并返回。(代理类型为接口StarService,原因是经纪人也得有明星的功能)
public static StarService createProxy(Star s){
/**
* 参数一:用于执行用哪个类加载器去加载生成的代理类。(固定写法,直接记住)
* 参数二:用于指定代理类需要实现的接口:明星类实现了哪些接口,代理类就实现哪些接口。(固定写法,直接记住)
* 参数三:用于指定代理类需要如何去代理(代理要做的事情)。
*/
StarService proxy = (StarService) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
s.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//用来声明代理对象要干的事情
//参数一:proxy接收到代理对象本身(暂时用处不大)
//参数二:method代表正在被代理的方法
//参数三:args代表正在被代理的方法的参数
String methodName = method.getName();
if("sing".equals(methodName)){
System.out.println("准备话筒,收钱20万!");
}else if("dance".equals(methodName)){
System.out.println("准备场地,收钱100万!");
}
//真正干活:把真正的明星对象叫过来干活
//找真正的明星对象来执行被代理的行为:method方法
Object result = method.invoke(s, args);//这一行代码是反射。 s是执行方法的对象,args是方法的参数
return result;
}
});
return proxy;
}
}
④编写测试类
⑤查看执行结果
4、执行逻辑
二、解决实际问题、掌握使用代理的好处
1、案例
给UserServiceImpl实习类中的每个方法,添加性能分析功能(统计方法执行耗时)
①原始写法:一个一个方法,添加代码,此时代码冗余,看起来十分繁琐
若此时,UserServiceImpl实现类中,有成千上万个方法,代码就十分冗余、繁琐。
②使用动态代理,完成UserServiceImpl实现类中的方法性能统计工作
③测试
④上面写的代理生成还不够通用,用泛型代替具体的类更加通用
这样一来,就不止UserServiceImpl可以用动态代理来进行耗时统计,其他实现类,比如ManagerServiceImpl、BookServiceImpl等实现类,也可以利用这个动态代理生成工具,来实现代码耗时统计。所以此时编写的这个动态代理,就十分通用、很顶级。
2、思想
①spring
Spring通过动态工厂,可根据一个对象生成一个代理对象,这个代理对象就可以理解为加强版的原来的对象。
就好比:我一个UserServiceImpl对象,根据动态代理对象生成工具类,可以生成一个代理对象,这个代理对象比原对象更加厉害,有统计方法耗时功能,得到了加强。
也好比:一个新生儿(原对象),通过防疫站(Spring)注射疫苗,得到了一个加强版的新生儿(代理对象),不容易被病毒侵害。
②AOP切面编程
AOP切面编程,底层可以使用动态代理技术来实现。
最后,动态代理等,这些比较高级的技术,以后写代码可能用不到,但是思想一定是必备的,掌握了就已经很OK了。
想了解更多关于Java的知识,请持续关注本博主~~
标签:Java,跳舞,对象,代理,明星,动态,method From: https://blog.csdn.net/qq_63981644/article/details/143049730