动态代理有jdk动态代理及cglib代理,下面描述jdk动态代理
jdk动态代理
看了 上云 老师的视频,整理下
pom文件
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency>
</dependencies>
目标类 IStudentServiceImpl
//目标执行接口
public interface IStudentService {void save();List<Student> query();
}//目标执行类实现
@Service
public class IStudentServiceImpl implements IStudentService {private static final Logger logger= LoggerFactory.getLogger(IStudentServiceImpl.class);@Overridepublic void save() {logger.info("新增功能...");}@Overridepublic List<Student> query() {logger.info("查询功能...");return new ArrayList<>();}
}
增强类 TransactionService
@Service
public class TransactionService{private static final Logger logger= LoggerFactory.getLogger(TransactionService.class);public void before(){logger.info("开始事务...");}public void after(){logger.info("结束事务...");}}
代理类
public class TransactionHandler implements InvocationHandler {private Object obj; //目标对象private TransactionService transactionService; //增强方法public TransactionHandler(Object obj, TransactionService transactionService) {this.obj = obj;this.transactionService = transactionService;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object result = null;if ("save".equals(method.getName())) {transactionService.before();result = method.invoke(obj,args);transactionService.after();} else {result = method.invoke(obj,args);}return result;}
}
Junit测试类
public class TestStudent {@Testpublic void test(){//增强类TransactionService transactionService=new TransactionService();//目标类对象IStudentService studentService=new IStudentServiceImpl();//方法拦截处理器TransactionHandler transactionHandler = new TransactionHandler(studentService, transactionService);//获取代理实例对象IStudentService proxyInstance = (IStudentService)Proxy.newProxyInstance(IStudentServiceImpl.class.getClassLoader(), IStudentServiceImpl.class.getInterfaces(), transactionHandler);proxyInstance.save();saveProxyClass("D:\\programs\\idea\\projects\\demo1\\src\\");}private void saveProxyClass(String path){byte[] proxy1s = ProxyGenerator.generateProxyClass("$Proxy1", IStudentServiceImpl.class.getInterfaces());FileOutputStream out=null;try {out=new FileOutputStream(new File(path+"$Proxy1.class"));out.write(proxy1s);} catch (Exception e) {e.printStackTrace();}finally {if(out!=null){try {out.flush();out.close();} catch (IOException e) {e.printStackTrace();}}}}
}
结论
可以看到:在src目录下生成一个class类[$Proxy1.class],此文件可以看到 该代理子类通过调用InvocationHandler的invoke方法实现了目标类的方法。
$Proxy1.class文件内容如下:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//import com.example.demo.service.IStudentService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.List;public final class $Proxy1 extends Proxy implements IStudentService {private static Method m1;private static Method m3;private static Method m4;private static Method m2;private static Method m0;public $Proxy1(InvocationHandler var1) throws {super(var1);}public final boolean equals(Object var1) throws {try {return (Boolean)super.h.invoke(this, m1, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final void save() throws {try {super.h.invoke(this, m3, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final List query() throws {try {return (List)super.h.invoke(this, m4, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final String toString() throws {try {return (String)super.h.invoke(this, m2, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final int hashCode() throws {try {return (Integer)super.h.invoke(this, m0, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}static {try {m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));m3 = Class.forName("com.example.demo.service.IStudentService").getMethod("save");m4 = Class.forName("com.example.demo.service.IStudentService").getMethod("query");m2 = Class.forName("java.lang.Object").getMethod("toString");m0 = Class.forName("java.lang.Object").getMethod("hashCode");} catch (NoSuchMethodException var2) {throw new NoSuchMethodError(var2.getMessage());} catch (ClassNotFoundException var3) {throw new NoClassDefFoundError(var3.getMessage());}}
}
由此可得出结论:底层实现了个Proxy的子类,Proxy里面有需要实现的增强方法,通过反射机制生成一个子类实现InvocationHandler接口,实现动态代理。
通过代理类对象调用方法时,会先调用其重写的invoke方法,里面再调用原方法。
- 通过实现接口获取到接口的所有方法[$Proxy1.class文件实现目标IStudentService类]
- 通过Proxy创建代理类实例[Proxy.newProxyInstance]
- 通过反射机制,获取到一个个的方法对象[$Proxy1.class类]
- 调用invocationHandler接口的invoke方法,从而实现业务的增强[TransactionHandler类文件实现InvocationHandler]