如何理解 Spring 中的 AOP
Spring 中的 AOP 实现原理
b、实现类:Spring 采用 cglib字节码增强。
a、Aop底层将采用代理机制进行实现 (最底层也是依赖反射) 。
1、对 AOP 的理解(画图解释)
2、AOP 中通过 JDK动态代理简单案例演示
public interface UserService { void addUser(); void updateUser(); int deleteUser(int id); } ========================================================================================= public class UserServiceImpl implements UserService { @Override public void addUser() { System.out.println("添加用户"); } @Override public void updateUser() { System.out.println("更新用户"); } @Override public int deleteUser(int id) { System.out.println("通过id删除用户"); return 1; } } 切面类 public class MyAspect { public void before(){ System.out.println("开启事务"); } public void after(){ System.out.println("提交事务"); } }
public class MyBeanFactory { // JDK实现动态代理 public static UserService createUserService() { //1.创建目标对象target final UserService userService = new UserServiceImpl(); //2.声明切面类对象 final MyAspect aspect = new MyAspect(); //3.把切面类2个方法应用于目标类 //3.1 创建JDK代理,拦截方法 UserService serviceProxy = (UserService) Proxy.newProxyInstance( MyBeanFactory.class.getClassLoader(), userService.getClass().getInterfaces(), (proxy, method, args) -> { //开启事务 aspect.before(); //方法返回值:业务方法的返回值 Object retObj = method.invoke(userService, args); //System.out.println("拦截返回值:" + retObj); //提交事务 aspect.after(); return retObj; } ); return serviceProxy; } }
public class AOPTest { public static void main(String[] args) { UserService userService = MyBeanFactory.createUserService(); userService.deleteUser(1); userService.addUser(); userService.updateUser(); } }
开启事务 通过id删除用户 提交事务 <=====================> 开启事务 添加用户 提交事务 <=====================> 开启事务 更新用户 提交事务 <=====================>
从测试结果可以看出,每次在执行业务代码的时候,会拦截对应的方法,执行切面类。
在 debug 测试函数: UserService userService = MyBeanFactory.createUserService();
可以看出直接得到的是代理对象,代理对象中就有实现的功能。
在 debug 测试函数: UserService userService = new UserServiceImpl();
可以看出直接得到的是其实现类,没有代理。
感兴趣的同学可以将测试函数中代码替换成上面两种。看看测试结果,以便于更好理解 AOP 思想。
3、AOP 中通过 CGlib 动态代理简单案例演示
public class StudentService { void delete() { System.out.println("删除用户"); } void add() { System.out.println("添加用户"); } void update() { System.out.println("更新用户"); } }
public class MyBeanFactory { // CGlib实现代理 public static StudentService createStudentService(){ //1.创建目标对象target final StudentService studentService = new StudentService(); //2.声明切面类对象 final MyAspect aspect = new MyAspect(); //3.创建增强对象 Enhancer enhancer = new Enhancer(); //设置父类 enhancer.setSuperclass(studentService.getClass()); //设置回调【拦截】 enhancer.setCallback((MethodInterceptor) (proxy, method, args, methodProxy) -> { aspect.before(); Object retObj = methodProxy.invokeSuper(proxy,args);//解藕 System.out.println("拦截....."); aspect.after(); return retObj; }); //创建代理对象 StudentService serviceProxy = (StudentService) enhancer.create(); //System.out.println("serviceProxy); return serviceProxy; } }
public class AOPTest { public static void main(String[] args) { StudentService studentService = MyBeanFactory.createStudentService(); studentService.add(); System.out.println("<=====================>"); studentService.delete(); System.out.println("<=====================>"); studentService.update(); System.out.println("<=====================>"); } }
开启事务 添加用户 拦截..... 提交事务 <=====================> 开启事务 删除用户 拦截..... 提交事务 <=====================> 开启事务 更新用户 拦截..... 提交事务 <=====================>
a、没有接口,只有实现类。 b、采用字节码增强框架 cglib,在运行时 创建目标类的子类,从而对目标类进行增强。