AOP原理
- 创建代理对象阶段
在Spring中,创建Bean实例都是从getBean()方法开始的,在实例创建之后,Spring容器将根据AOP的配置去匹配目标类的类名,看目标类的类名是否满足切面规则。
如果满足切面规则,就会调用ProxyFactory创建代理Bean并缓存到IOC容器中。根据目标对象的自动选择不同的代理策略。如果目标类实现了接口,Spring会默认选择JDK Proxy,如果目标类没有实现接口,Spring会默认选择Cglib Proxy。
- 拦截目标对象阶段
当用户调用目标对象的某个方法时,将会被一个叫做AopProxy的对象拦截,Spring将所有的调用策略封装到了这个对象中,它默认实现了InvocationHandler接口,也就是调用代理对象的外层拦截器。在这个接口的invoke()方法中,会出发MethodInvocation的proceed()方法。在这个方法中会按顺序执行符合所有AOP拦截规则的拦截器链。
- 调用代理对象阶段
Spring AOP拦截器链中的每个元素被命名为MethodInterceptor,其实就是切面配置中的Advice通知。这个回调可以简单地理解为是新生成的代理Bean中的方法。也就是我们常说的被织入的代码片段,这些被织入的代码片段会在这个阶段执行。
- 调用目标对象阶段
MethodInterceptor接口也有一个invoke()方法,在MethodInterceptor的invoke()方法中会触发对目标对象方法的调用,也就是反射调用目标对象的方法。
总结
流程:
-
代理对象:就是由Spring代理策略生成的对象;
-
目标对象:就是我们自己写的业务代码;
-
织入代码:就是要在我们自己写的业务代码增加的代码片段;
-
切面通知:就是封装织入代码片段的回调方法;
-
MethodInvocation:负责执行拦截器链,在proceed()方法中执行;
-
MethodInterceptor:负责执行织入的代码片段,在invoke()方法中执行。