Spring注解(十三) AOP运行机制

147 阅读2分钟

总结 没看懂 以后再说

从@EnableAspectJAutoProxy开始

@EnableAspectJAutoProxy

@Import(AspectJAutoProxyRegistrar.class) //导入了AspectJAutoProxyRegistrar
public @interface EnableAspectJAutoProxy {

AspectJAutoProxyRegistrar

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

![](p3-juejin.byteimg.com/tos-cn-i- k3u1fbpfcp/d781ae24465c4ffd9ec1f2b4c28039d5~tplv-k3u1fbpfcp-zoom-1.image) 利用AspectJAutoProxyRegistrar给容器注册bean 注册了AnnotationAwareAspectJAutoProxyCreator.class 这是第一步 : 往容器加入注册了AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator有什么用?

父类中实现了SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware,也就是后置处理器,

SmartInstantiationAwareBeanPostProcessor BeanFactoryAware

于是到父类中, 打断点看看后置处理器在做什么

  • setBeanFactory 断点
  • initBeanFactory断点
  • postProcessBeforeInitialization
public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }

    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                return this.wrapIfNecessary(bean, beanName, cacheKey);
            }
        }

        return bean;
    }

结果

  • registerBeanPostProcessors(beanFactory); 中发生的 创建 AnnotationAwareAspectJAutoProxyCreator 放入容器中的过程, AnnotationAwareAspectJAutoProxyCreator实现了后置处理器接口, 因此也是后置处理器对象,相当于把他放入了容器中, 接下来所有的bean创建要被这个aop的后置处理器拦截.

下一步

  • finishBeanFactoryInitialization(beanFactory);中发生的// 创建剩下的单实例bean
    • 遍历所有bean, 判断有没有创建放在缓存中, 还没创建就创建
    • createBean
      • resolveBeforeInstantiation希望后置处理器在此能返回代理对象, 如果能就使用代理对象, 不能对酒create
        • 后置处理器先尝试返回对象bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
  • 结论AnnotationAwareAspectJAutoProxyCreator这个后置处理器会拦截实例创建, 在创建之前调用postProcessBeforeInstantiation

postProcessBeforeInstantiation bean创建之前

判断bean是不是需要增强,

@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
		Object cacheKey = getCacheKey(beanClass, beanName);

		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}

wrapIFNessary, 返回增强bean

AnnotationAwareAspectJAutoProxyCreator有什么用 特点在于会在创建所有bean之前拦截bean, 和普通后置处理器不一样, 然后就判断是不是切面bean

容器 调用refresh

  • 创建AnnotationAwareAspectJAutoProxyCreator 放入容器
  • 初始化剩下的bean
    • 创建切面组件
    • 和普通类 初始化过程AnnotationAwareAspectJAutoProxyCreator拦截
    • 判断是否需要包装增强
      • 是 包装成Advisor 创建代理对象cglib 代理对象执行目标方法 cglibaopproxy.intercept() 拦截器 拦截器链, 每一个拦截器拦截执行 正常 前置通知->目标方法->后置通知->返回通知 异常 前置通知->目标方法->后置通知->异常通知