版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/May_3/article/details/79595432
写在前面:
Spring框架AOP的核心就是动态代理,动态代理又分为JDK代理和Cglib代理,这篇博客先来总结JDK代理的方法。JDK代理的核心是反射。所以要想手动实现动态代理,必须要实现InvocationHandler接口,并且有Proxy类动态创建一个代理对象。
InvocationHandler:
InvocationHandler接口中只有一个方法:invoke方法。invoke会传入3个参数,proxy为被代理的对象。method,被代理的对象的方法,args调用对象方法接受的参数。
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
Proxy:
Proxy类中的重要方法就是newProxyInstance,用于动态创建一个代理对象。loader定义由哪一个classLoader加载目标对象,interfaces是一个数组对象,表示给代理对象提供的一组接口,handler则是一个InvocationHandler对象,表示当动态代理对象在调用方法的时候,会关联到的InvocationHandler对象。
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler handler)
代理对象创建案例:
IUserDao接口:
package dynamic;
public interface IUserDao {
public void save();
}
UserDao类:
package dynamic;
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("-----使用动态代理------");
}
}
动态代理类:
package dynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 动态代理类
* @ClassName ProxyFactory
* @Description
* @author McGRADY
* @date 2018年3月17日
*/
public class ProxyFactory {
// 维护一个目标对象
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
// 给目标对象生产代理对象
public Object getProxyInstance() {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开启事务");
Object returnvalue = method.invoke(target, args);
System.out.println("提交事务");
return returnvalue;
}
});
}
}
测试类:
package dynamic;
public class APP {
public static void main(String[]args) {
//目标对象
IUserDao target = new UserDao();
System.out.println(target.getClass());
//创建代理对象
IUserDao proxy=(IUserDao) new ProxyFactory(target).getProxyInstance();
System.out.println(proxy.getClass());
proxy.save();
}
}
控制台输出:
class dynamic.UserDao
class com.sun.proxy.$Proxy0
开启事务
-----使用动态代理------
提交事务