2. 动态代理
动态代理的底层都是反射
- 动态代理和静态代理角色一样
- 动态代理的代理类是动态生成的,不是我们写好的
- 动态代理分为两大类:基于接口的动态代理;基于类的动态代理
- 基于接口–jdk动态代理
- 基于类—cglib
- java字节码实现:javassist
- 动态代理代理的是接口
需要了解两个类:Proxy:代理;InvocationHandler:调用处理程序
InvocationHandler:反射包(java.lang.reflect)下的。它是由代理实例的,调用处理程序实现的接口。每个代理实例都有一个关联的调用处理程序,当在代理实例上调用方法时,方法调用将编码并分派到其调用处理程序的invoke方法
动态代理的好处:
- 可以使真实角色的操作更加纯粹,不用取关注一些公共的业务
- 公共业务交给代理角色,实现业务的分工
- 公共业务发生扩展的时候,方便集中管理
- 一个动态代理类代理的是一个接口,一般就是对应的一类业务
- 一个动态代理类可以代理多个类,只要是实现了同一个接口即可
2.1初次理解
不去写代理角色,让他自己生成。
package com.hxl.demo03; public class Host implements Rent{ public void rent() { System.out.println("房东要租房"); } }
package com.hxl.demo03; //租房 public interface Rent { public void rent(); }
代理的类
package com.hxl.demo03; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; //等会会用这个类自动生成代理类 public class ProxyInvocationHandler implements InvocationHandler { //被代理的接口 private Rent rent; public void setRent(Rent rent) { this.rent = rent; } //生成得到代理类 public Object getProxy(){ Object o = Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this); return o; } //处理代理实例,并返回结果 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { seeHouse(); //动态代理的本质,就是使用反射机制实现 Object result = method.invoke(rent, args); fare(); return result; } public void seeHouse(){ System.out.println("中介带着看房子"); } public void fare(){ System.out.println("租赁合同"); } }
测试:
package com.hxl.demo03; public class Client { public static void main(String[] args) { //真实角色 Host host = new Host(); //代理角色:现在没有 ProxyInvocationHandler pih = new ProxyInvocationHandler(); //通过调用程序处理角色来处理我们要调用的接口对象 pih.setRent(host); //获得代理类 Rent proxy = (Rent) pih.getProxy();//这里的proxy就是动态生成的,我们并没有写 proxy.rent(); } }
2.2 再深理解
我们把它弄成一个公式类似于。弄得活起来,智能化
代理:
package com.hxl.demo04; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; //等会会用这个类自动生成代理类 public class ProxyInvocationHandler implements InvocationHandler { //被代理的接口. //这里把它变活 private Object target; public void setTarget(Object target) { this.target = target; } //生成得到代理类 public Object getProxy(){ Object o = Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this); return o; } //处理代理实例,并返回结果 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //可以写死,比如搞成log.add();但是不智能,所以要弄活 log(method.getName()); //动态代理的本质,就是使用反射机制实现 Object result = method.invoke(target, args); return result; } public void log(String msg){ System.out.println("执行了" + msg + "方法"); } }
测试:
package com.hxl.demo04; import com.hxl.demo02.UserService; import com.hxl.demo02.UserServiceImpl; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class Client { public static void main(String[] args) { //真实角色 UserServiceImpl userService = new UserServiceImpl(); //代理角色。不存在 ProxyInvocationHandler pih = new ProxyInvocationHandler(); //设置要代理的对象 pih.setTarget(userService); //动态生成代理类 UserService proxy = (UserService) pih.getProxy(); proxy.add(); } }