AOP对象是如何创建的
对于熟悉Spring IOC流程源码的同学来说,一定了解bean的整个生命周期,也就是从实例化、属性填充、初始化三个过程。那么对于Bean 工厂来说,是如何保证需要创建代理的对象创建代理的呢。
从图中可以看到,本质是通过注解 @EnableAspectJAutoProxy
, 通过引入 @Import(AspectJAutoProxyRegistrar.class)
顶层其实就是一个BPP
核心调用流程图就在这里,这里可以通过debug的方式查找。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(MyAopAspectJPostProcessor.class)
public @interface MyEnableAspectjAutoProxy {
}
@Configuration
@ComponentScan("com.qxlx.aopprocessor")
@MyEnableAspectjAutoProxy
public class Config {}
最终通过自定义注解的方式 也实现了这种一个简易版本的AOP
详解 @EnableAspectJAutoProxy
proxyTargetClass
/*** Indicate whether subclass-based (CGLIB) proxies are to be created as opposed* to standard Java interface-based proxies. The default is {@code false}.*/boolean proxyTargetClass() default false;
其实就是是否基于CGlib进行动态代理对于接口,默认时false。
exposeProxy
/*** Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}* for retrieval via the {@link org.springframework.aop.framework.AopContext} class.* Off by default, i.e. no guarantees that {@code AopContext} access will work.* @since 4.3.1*/boolean exposeProxy() default false;
其实这个字段的含义就是从4.3.1 版本开始,如果设置为true的话,会把当前对象的代理对象存储到ThreadLocal对象中。
// 可以用来解决 本类同方法调用事务失效时 获取代理对象IUserService userService = (IUserService) AopContext.currentProxy();userService.delete();
其实就是根据exposeProxy的值 判断是否true,将当前代理对象存储到ThreadLocal中。
// JdkDynamicAopProxy 代理if (this.advised.exposeProxy) {// Make invocation available if necessary.oldProxy = AopContext.setCurrentProxy(proxy);setProxyContext = true;}
// 本质其实就是ThreadLocal private static final ThreadLocal<Object> currentProxy = new NamedThreadLocal<>("Current AOP proxy");
AnnotationAwareAspectJAutoProxyCreator
再往下看的话 其实就是分别JDK和Cglib生成代理的代码了。
1.BeanPostProcess创建代理。考虑循环引用问题
2.ProxyFactory
setTarget、setAdvisor、
3.底层的代码
AOPProxy
CglibAopProxy
JdkDnmiacAopProxy
1.AOP创建了动态代理
2.动态字节码动态 运行时执行 是如何执行的?
代理是在运行的过程中,才会把原始对象的功能与额外功能进行整合。
动态代理 运行效率低于静态代理
代理类执行过程
这里总整体进行总结下,一个是代理对象的生成,是在bean after BPP阶段进行调用生成的,另外一个就是实际方法的调用就是在原有的类基础上代理类加了拦截表达式,根据表达式判断当前方法是否需要执行对应的前置 后置 等方法,完整额外功能的添加。
感兴趣的可以通过 看 具体的源码
https://github.com/qxlx/spring-code/blob/main/src/main/java/com/qxlx/aopprocessor/