一,动态代理介绍
- 动态代理和静态代理的角色都是一样,静态代理模式的代理类是我们提前写好的,而动态代理的类是动态生成的,其实动态代理与静态代理的本质一样,最终程序运行时都需要生成一个代理对象实例,通过它来完成相关增强以及业务逻辑,只不过静态代理需要硬编码的方式指定,而动态代理支持运行时动态生成这种实现方式。动态生成的好处很明显,在编码时,代理逻辑与业务逻辑互相独立,各不影响,没有侵入,没有耦合
二,与动态代理相关的两个类
- Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method,Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组。这个抽象方法在代理类中动态实现
- Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject,其中主要包含以下内容:
Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。
Static Class getProxyClass (ClassLoader loader,Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组
三,代码实现动态代理
1,抽象角色
1 //抽象角色 2 public interface User { 3 4 public void add(); 5 6 }
2,真实角色
1 //真实角色 2 public class UserImpl implements User { 3 4 public void add() { 5 System.out.println("这是一个add方法"); 6 } 7 8 }
3,动态代理类生成的接口对象
1 import java.lang.reflect.InvocationHandler; 2 import java.lang.reflect.Method; 3 import java.lang.reflect.Proxy; 4 5 public class InvocationHandlerProxy implements InvocationHandler { 6 7 private User user; 8 9 public void setUser(User user) { 10 this.user = user; 11 } 12 13 //动态生成代理类 14 public Object getProxy(){ 15 return Proxy.newProxyInstance(this.getClass().getClassLoader(), 16 user.getClass().getInterfaces(),this); 17 } 18 19 //proxy:代理类 20 //method:代理类的调用处理程序的方法 的对象 21 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 22 show1(); 23 Object invoke = method.invoke(user, args); 24 show2(); 25 return invoke; 26 } 27 28 public void show1(){ 29 System.out.println("show方法1"); 30 } 31 32 public void show2(){ 33 System.out.println("show方法2"); 34 } 35 }
【注意InvocationHandler导包】
4,测试
1 public class Test { 2 public static void main(String[] args) { 3 4 UserImpl userImpl = new UserImpl(); 5 6 InvocationHandlerProxy ihp = new InvocationHandlerProxy(); 7 ihp.setUser(userImpl); 8 9 User proxy = (User) ihp.getProxy(); 10 11 proxy.add(); 12 } 13 }
5,运行结果
四,总结
动态代理的好处
- 可以使真实角色更加纯粹,不用去关注一些公共的事情
- 公共的业务由代理来完成,实现业务的分工
- 公共业务的要扩展的话,可以更加集中和方便
- 一个动态代理,一般代理一类的业务,一个动态代理可以代理多个类,代理接口