代理:其目的就是为其他对象提供一个代理以控制对某个对象的访问。(代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息把被委托执行后的后续处理)
java动态代理类位于 java.lang.reflect包下,一般主要涉及以下两个类:
(1)interface IvocationHandler 该接口中仅定义了一个方法
第一个参数 var1 一般是指代理类
第二个参数 var2 是被代理的方法
第三个参数 var3 是该方法的参数
这个抽象方法在代理类中动态实现
(2)Proxy:该类即为动态代理类:其中包含一下内容
protected Proxy(InvocationHandler) :构造方法,用于给内部h赋值
getProxyClass(...);获得一个代理类,loader是类加载器,interfaces是真实类的接口数组
newProxyInstance(...):返回代理类的一个实例,返回后的代理类可以被当作代理类使用(可执行对应方法)
所谓DynamicProxy是这样一种class::他是运行时生成的class,在生成它时必须提供一组Interface给它,然后该class就宣称它实现了这些interface。当然,这个DynamicProxy其实就是要给Proxy,他不会替你实质性工作,在生成它的实例时你必须提供一个handler,由他接管实际工作。
在使用动态代理类时,我们必须实现InvocationHandler接口
动态代理步骤:
1.创建一个实现接口InvocationHandler的类,他必须实现invoke方法
2.创建被代理的类及接口
3.通过Proxy的静态方法 newProxyInstance(...) 创建一个代理
4.通过代理调用方法
代码实例:
/** * 需要代理的接口 */ public interface Person { /** * 跑 * @return */ String run(); /** * 吃 * @return */ String eat(); /** * 喝 * @return */ String dirnk(); }
/** * 实现类 */ public class Man implements Person { @Override public String run() { return "男人跑"; } @Override public String eat() { return "男人吃"; } @Override public String dirnk() { return "男人喝水"; } }
/** * 动态代理 */ @Slf4j public class DynamicProxy01 implements InvocationHandler { private Object target; public DynamicProxy01(Object target) { this.target = target; } /** * * @param o 被代理的类 * @param method 方法 * @param objects 参数 * @return * @throws Throwable */ @Override public Object invoke(Object o, Method method, Object[] objects) throws Throwable { log.info("代理方法 {} 之前执行" ,method.getName()); log.info("哈哈,代理执行的方法,结果如下 = {} ",method.invoke(target,objects)); log.info("代理方法 {} 之后执行" ,method.getName()); return null; } }
public class TestProxy { @Test public void test1(){ Person person = new Man(); DynamicProxy01 dynamicProxy = new DynamicProxy01(person); Person o = (Person) Proxy.newProxyInstance(dynamicProxy.getClass().getClassLoader(), Man.class.getInterfaces(), dynamicProxy); o.run(); o.eat(); o.dirnk(); } }