Spring 底层 AOP 的实现原理
创建目标类。
public class UserDaoImpl implements UserDao { public void save() { System.out.println("保存用户!"); } public void select() { System.out.println("查询用户!"); } public void delete() { System.out.println("删除用户!"); } public void update() { System.out.println("更新用户!"); } }
一、JDK 动态代理增强一个类中方法。
(一)创建MyJDKProxy工具类,并实现InvocationHandler。
public class MyJDKProxy implements InvocationHandler { // 生成带参数的构造方法 public MyJDKProxy(UserDao userDao) { super(); this.userDao = userDao; } private UserDao userDao; // 编写工具类:生成代理 public UserDao createProxy() { // 生成动态代理 UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance( userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), this); return userDaoProxy; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if("save".equals(method.getName())){ System.out.println("权限校验============="); } return method.invoke(userDao, args); } }
(二)编写测试方法
@Test public void fun3(){ // 创建接口对象 UserDao userDao = new UserDaoImpl(); // 创建动态代理对象,将接口对象当做参数传入 MyJDKProxy proxy = new MyJDKProxy(userDao); // 调用生成代理的方法 UserDao userProxy = proxy.createProxy(); userProxy.save(); }
二、Cglib 动态代理增强一个类中的方法。
(一)创建MyCglibProxy工具类,并实现MethodInterceptor接口。
public class MyCglibProxy implements MethodInterceptor{ private UserDaoImpl userDao; public MyCglibProxy(UserDaoImpl userDao){ this.userDao = userDao; } // 生成代理的方法 public UserDaoImpl createProxy(){ // 创建Cglib核心类 Enhancer enhancer = new Enhancer(); // 设置父类 enhancer.setSuperclass(userDao.getClass()); // 设置回调 enhancer.setCallback(this); // 生成代理 UserDaoImpl create = (UserDaoImpl) enhancer.create(); return create; } public Object intercept(Object userDao, Method method, Object[] args, MethodProxy proxy) throws Throwable { if("select".equals(method.getName())){ System.out.println("日志记录============="); Object object = proxy.invokeSuper(userDao, args); return object; } return proxy.invokeSuper(proxy, args); } }
(二)测试方法。
@Test public void fun4(){ UserDaoImpl userDao = new UserDaoImpl(); MyCglibProxy cglibProxy = new MyCglibProxy(userDao); UserDaoImpl createProxy = cglibProxy.createProxy(); createProxy.select(); }