代理模式---动态代理模式
1. 动态代理
- 动态代理和静态代理一样
- 动态代理的代理类是动态生成的,不是我们直接写好的
- 动态代理分为两大类:
基与接口的动态代理----JDK动态代理
基于类的动态代理---cglib动态代理
java字节码实现:javassist
动态代理需要了解两个类:Proxy代理类,InvocationHandler调用处理程序
2. 动态代理的demo实现
1.接口
1 public interface Rent { 2 public void rent(); 3 }
2.真实角色(真实角色实现接口)
public class Host implements Rent { @Override public void rent() { System.out.println("房东要租房子"); } }
3.代理对象,动态生成代理类
自动生成代理类时,需要封装被代理的接口,实现set方法
生成代理类:固定的步骤,需要修改的只有被代理的接口rent
处理代理实例:固定的步骤,动态代理的本质就是使用反射机制实现
1 //使用这个类自动生成代理类 2 public class ProxyInvocationHandler implements InvocationHandler { 3 //被代理的接口 4 private Rent rent; 5 public void setRent(Rent rent){ 6 this.rent=rent; 7 } 8 //生成得到的代理类 9 public Object getProxy(){ 10 return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this); 11 12 } 13 //处理代理实例,返回结果 14 @Override 15 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 16 //动态代理的本质就是使用反射机制实现 17 Object result = method.invoke(rent,args); 18 return result; 19 } 20 }
4.客户端访问代理角色
代理角色需要动态生成,通过调用程序处理角色来处理我们要调用的接口对象
1 public class Client { 2 public static void main(String[] args) { 3 //真实角色 4 Host host=new Host(); 5 //代理角色,目前没有,需要动态生成 6 ProxyInvocationHandler pih = new ProxyInvocationHandler(); 7 //通过调用程序处理角色来处理我们要调用的接口对象 8 pih.setRent(host); 9 //这里的proxy是动态生成的 10 Rent proxy=(Rent)pih.getProxy(); 11 proxy.rent(); 12 } 13 }
3. 动态代理的优化
1. 动态生成代理对象的模板
1 public class ProxyInvocationHandler implements InvocationHandler { 2 //被代理的接口 3 private Object target; 4 5 public void setTarget(Object target) { 6 this.target = target; 7 } 8 9 //生成得到的代理类 10 public Object getProxy(){ 11 return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this); 12 13 } 14 //处理代理实例,返回结果 15 @Override 16 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 17 //动态代理的本质就是使用反射机制实现 18 Object result = method.invoke(target,args); 19 return result; 20 } 21 }
2. 客户端访问代理对象
1 public class Client { 2 public static void main(String[] args) { 3 //真实角色 4 ServiceImpl service=new ServiceImpl(); 5 //代理角色 6 ProxyInvocationHandler pih = new ProxyInvocationHandler(); 7 //设置要代理的对象 8 pih.setTarget(service); 9 //动态生成代理类 10 Service proxy=(Service) pih.getProxy(); 11 //调用功能 12 proxy.add(); 13 } 14 }
4. 动态代理的好处
- 可以使真实角色的操作更加纯粹,不用去关注一些公共的业务
- 公共业务交给代理角色,实现业务的分工
- 公共业务发生拓展的时候,方便管理
- 一个动态代理类代理的是一个接口,一般对应的是一类业务
- 一个动态代理类可以代理多个类,只要实现同一个接口即可
浙公网安备 33010602011771号