动态代理有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);
@Override
public void save() {
logger.info("新增功能...");
}
@Override
public 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;
}
@Override
public 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 {
@Test
public 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方法,里面再调用原方法。