动态代理
动态代理是指,程序在整个运行构成中根本就不存在目标类的代理类,目标对象的代理对象只是由代理生成工具(不是真实定义的类)在程序运行时由JVM根据反射等机制动态生成的。代理对象与目标对象的代理关系在程序运行时才确立。
一、JDK动态代理
动态代理的实现方式常用的有两种:使用JDK的Proxy,与通过CGLIB生成代理。jdk的动态要求目标对象必须实现接口,这是Java设计上的要求。
从jdk1.3以来,Java语言通过java.lang.reflect包提供三个支持代理模式Proxy,Method和InvocationHandler。
二、JDK动态代理实现步骤:
1.创建目录类,SomeServiceImpl目标类,给它的doSome,doOther增加输出时间和事务。
2.创建InvocHandler接口的实现类,在这个类实现给目标方法增加功能。
package com.hlc.handler; import com.hlc.util.ServiceTools; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler { //目标对象 private Object target; //SomeServiceImpl类 public MyInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //通过代理对象执行时,会调用执行invoke() Object res = null; ServiceTools.doLog(); //执行目标类的方法,通过Method类实现 res = method.invoke(target,args); //SomeServiceImpl , doOther() , doSome() ServiceTools.doTrans(); //目标方法的执行结果 return res; } }
3.使用jdk中类Proxy,创建代理对象。实现创建对象的能力。
package com.hlc; import com.hlc.handler.MyInvocationHandler; import com.hlc.service.SomeService; import com.hlc.service.impl.SomeServiceImpl; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class MyApp { public static void main(String[] args) { //使用jdk的Proxy创建代理对象 //创建目标对象 SomeService target = new SomeServiceImpl(); //使用InvocationHandler对象 InvocationHandler handler = new MyInvocationHandler(target); //使用Proxy创建代理 SomeService proxy = (SomeService) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(),handler ); //通过代理执行方法,会调用handler中的invoke() proxy.doSome(); } }
运行结果:
执行了MyInvocationHandler中的involved
非业务方法,方法的执行时间:Mon Jul 26 00:25:49 CST 2021
执行业务方法doSome
方法执行完毕后,提交事务