1.JDK动态代理,目标类和代理类继承同样的接口
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import cn.zzsxt.dao.impl.StudentDao;
import cn.zzsxt.dao.impl.StudentDaoImpl;
/**
* JDK动态代理
* 前提:要求被代理必须实现接口
* 本质:通过反射机制动态生成指定接口(和被代理目标实现相同的接口)的实现类
*/
public class JDKProxy implements InvocationHandler{
private Object target;//被代理目标
public Object getProxy(Object target){
this.target=target;
/**
* loader - 定义代理类的类加载器,通常和被代理目标使用相同的加载器
* interfaces - 代理类要实现的接口列表,通常和被代理目标实现相同的接口
* h - 指派方法调用的调用处理程序
*/
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
}
/**
* 在代理实例上处理方法调用并返回结果
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开启事务....");
Object object = method.invoke(target, args);//回调被代理目标中的方法
System.out.println("提交事务...");
return object;
}
public static void main(String[] args) {
JDKProxy jdkProxy = new JDKProxy();
//向上转型
StudentDao studentDao = (StudentDao)jdkProxy.getProxy(new StudentDaoImpl());
studentDao.save();
}
}
2.基于caglib的动态代理,目标类没有实现任何的接口,创建目标类的子类,通过子类得到代理类。不管是基于jdk或者caglib都是通过invoke的回调方法动态代理
package cn.zzsxt.cglib;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
* cglib代理:基于父类(要求被代理目标非final修饰的类)应为final修饰的类不能被继承
* 本质:生成一个被代理目标的子类,当访问业务方法时将委派给intercept()方法进行处理
* @author Think
*
*/
public class CglibProxy implements MethodInterceptor{
private Object target;//被代理目标
/**
* 生产一个代理
* @return
*/
public Object getProxy(Object target){
this.target=target;
//1.创建Enhancer对象
Enhancer enhancer = new Enhancer();
//2.设置超类
enhancer.setSuperclass(target.getClass());
//3.设置回调函数
enhancer.setCallback(this);
//4.调用create方法创建代理
return enhancer.create();
}
/**
*类似于JDK动态代理中的invoke方法
*/
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("开启事务....");
Object object = method.invoke(target, args);//回调被代理目标的方法
System.out.println("提交事务...");
return object;
}
public static void main(String[] args) {
CglibProxy cglibProxy = new CglibProxy();
TeacherDao teacherDao = (TeacherDao)cglibProxy.getProxy(new TeacherDao());
teacherDao.save();
}
}