spring AOP
一、定义
面向切面编程(AOP)是对面向对象编程(OOP)的补充,面向对象编程擅长处理纵向问题,对横向问题无能为力,而面向切面编程主要解决的就是 横向问题。
AOP(Aspect-Oriented Programming)作为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。可用于权限认证、日志、事务处理等。
二、aop的应用场景有哪些:
场景一: 记录日志
场景二: 监控方法运行时间 (监控性能)
场景三: 权限控制
场景四: 缓存优化 (第一次调用查询数据库,将查询结果放入内存对象, 第二次调用, 直接从内存对象返回,不需要查询数据库 )
场景五: 事务管理 (调用方法前开启事务, 调用方法后提交关闭事务 )
三、springAop的底层是怎样实现的?是编译时期进行织入,还是运行期进行织入?
1、JDK动态代理
2、CGLIB代理
运行期,生成字节码,再加载到虚拟机中,JDK是利用反射原理,CGLIB使用了ASM原理。
四、spring AOP 默认使用jdk动态代理还是cglib?
要看条件,如果实现了接口的类,是使用jdk。如果没实现接口,就使用cglib。
https://blog.csdn.net/u010452388/article/details/80868392
五 AOP的作用
作用:在不修改源代码的情况下,可以实现功能的增强。
传统的纵向体系代码复用:
横向抽取机制(AOP思想):
AOP 思想: 基于代理思想,对原来目标对象,创建代理对象,在不修改原对象代码情况下,通过代理对象,调用增强功能的代码,从而对原有业务方法进行增强 !
六、AOP实现原理:
1.jdk动态代理:
public interface UserDao { public void saveUser(); }
public class UserDaoImpl implements UserDao { @Override public void saveUser() { System.out.println("持久层:用户保存"); } }
@Test public void test1() { final UserDao userDao = new UserDaoImpl(); // newProxyInstance的三个参数解释: // 参数1:代理类的类加载器,同目标类的类加载器 // 参数2:代理类要实现的接口列表,同目标类实现的接口列表 // 参数3:回调,是一个InvocationHandler接口的实现对象,当调用代理对象的方法时,执行的是回调中的invoke方法 //proxy为代理对象 UserDao proxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), new InvocationHandler() { @Override // 参数proxy:被代理的对象 // 参数method:执行的方法,代理对象执行哪个方法,method就是哪个方法 // 参数args:执行方法的参数 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("记录日志"); Object result = method.invoke(userDao, args); return result; } }); //代理对象执行方法 proxy.saveUser(); }
运行结果:
在没有修改原有类的代码的情况下,对原有类的功能进行了增强
2.cglib动态代理
在实际开发中,可能需要对没有实现接口的类增强,用JDK动态代理的方式就没法实现。采用Cglib动态代理可以对没有实现接口的类产生代理,实际上是生成了目标类的子类来增强。