(一)JDK的动态代理
原理: JDK动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
JDK的动态代理 必须是实现了接口的类
1 接口
public interface UserDao { public void saveUser(); }
2 实现类
public class UserDaoImpl implements UserDao { @Override public void saveUser() { System.out.println("用户保存成功"); } }
3 测试类编写
@Test void test1() { //JDK的动态代理,必须要有接口 UserDao userDao = new UserDaoImpl(); UserDao dao = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), new InvocationHandler() { // 参数proxy:被代理的对象 // 参数method:执行的方法,代理对象执行哪个方法,method就是哪个方法 // 参数args:执行方法的参数 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("JDK代理前 do something!!! (例如记录日志)"); Object result = method.invoke(userDao, args); return result; } }); dao.saveUser(); }
4 运行结果
(二)CGLIB的动态代理
可以是没有实现接口的类
1 保存方法
public class CglibDao { public void save(){ System.out.println("保存成功!!!!!"); } }
2 测试类编写
@Test void test2(){ final CglibDao cglibDao = new CglibDao(); //创建cglib的核心对象 Enhancer enhance = new Enhancer(); //设置父类 enhance.setSuperclass(cglibDao.getClass()); //设置回调 enhance.setCallback(new MethodInterceptor() { /** * 当你调用目标方法时,实质上是调用该方法 * intercept四个参数: * proxy:代理对象 * method:目标方法 * args:目标方法的形参 * methodProxy:代理方法 */ @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("CGLIB代理前 dosomething!!!!!! (例如记录日志)"); Object result = method.invoke(cglibDao, args); return result; } }); CglibDao dao = (CglibDao) enhance.create(); dao.save(); }
3 运行结果
原来如此