Aop源码分析

基础知识

  • == 前提:需要了解Spring的IOC容器初始化过程==
  • 疑问:
    1. 我们都知道aop是基于动态代理来实现aop的,那么aop的动态代理是在什么时候进行创建的?
    2. 在使用aop进行切面编程的时候,又是怎么运行的?
  •  参考视频:https://www.bilibili.com/video/BV1ME411o7Uu?p=29
    

重要的BeanPostProcessor

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

    Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;

    boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;
	//将在注入properties之前触发,可以对整理好的properties进行修改
    PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;

}
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
    Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException;

    //用于bean初始化的时候决定调用哪一个构造函数
    Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException;

    //解决循环依赖的问题 后面会在三级缓存中总结
    Object getEarlyBeanReference(Object bean, String beanName) throws BeansException;

}

aop如何进行动态创建代理对象

  • @EnableAspectJAutoProxy是什么

    @Import(AspectJAutoProxyRegistrar.class)
    利用AspectJAutoProxyRegistrar给容器注入组件
    	@Override
    	public void registerBeanDefinitions(
    			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    
        	//1.如果有internalAutoProxyCreator 直接返回注册 
        	//2.没有beanDefinition = new RootBeanDefinition(AnnotationAwareAspectJAutoProxyCreator);
    		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
    
    		AnnotationAttributes enableAspectJAutoProxy =
    				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
        
    		if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
    			AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
    		}
    		if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
    			AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
    		}
    	}
    
  • AnnotationAwareAspectJAutoProxyCreator可以做什么?

    image

    从类关系上分析我们需要关注后置处理器工作

  • AbstractAutoProxyCreator

    //会被AbstractAdvisorAutoProxyCreator重写
    public void setBeanFactory(BeanFactory beanFactory) {
       this.beanFactory = beanFactory;
    }
    
  • AbstractAdvisorAutoProxyCreator

    public void setBeanFactory(BeanFactory beanFactory) {
       super.setBeanFactory(beanFactory);
       if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
          throw new IllegalArgumentException(
                "AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
       }
       initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
    }
    
    //会被AnnotationAwareAspectJAutoProxyCreator重写
    protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
       this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
    }
    
  • AnnotationAwareAspectJAutoProxyCreator

    protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
       super.initBeanFactory(beanFactory);
       if (this.aspectJAdvisorFactory == null) {
          this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
       }
       this.aspectJAdvisorsBuilder =
             new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
    }
    
  • 流程

    1. 创建ioc容器(参考IOC容器初始化文章)

    2. AnnotationAwareAspectJAutoProxyCreator创建

      this.aspectJAdvisorsBuilder =
            new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
      
    3. ​ createBean->resolveBeforeInstantiation(beanName, mbdToUse); **这里并没有到doCreatbean() **

      protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
         for (BeanPostProcessor bp : getBeanPostProcessors()) {
             //注意InstantiationAwareBeanPostProcessor 因为AnnotationAwareAspectJAutoProxyCreator实现了 所以这里才会执行
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
               InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
               Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
               if (result != null) {
                  return result;
               }
            }
         }
         return null;
      }
      
    4. 创建AOP代理

      public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
         Object cacheKey = getCacheKey(beanClass, beanName);
      
         if (beanName == null || !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;
            }
         }
      
         // Create proxy here if we have a custom TargetSource.
         // Suppresses unnecessary default instantiation of the target bean:
         // The TargetSource will handle target instances in a custom fashion.
         if (beanName != null) {
            TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
            if (targetSource != null) {
               this.targetSourcedBeans.add(beanName);
               Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
               Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
               this.proxyTypes.put(cacheKey, proxy.getClass());
               return proxy;
            }
         }
      
         return null;
      }
      
      1. 判断bean是否在advisedBeans中(所有需要代理的Bean)

      2. 判断是否实现了isInfrastructureClass()

      3. 判断Bean是否是切面类shouldSkip() List candidateAdvisors

      4. postProcessAfterInitialization()->wrapIfNecessary()
            
         //获取所有的增强器 也就是 切面通知方法
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        		if (specificInterceptors != DO_NOT_PROXY) {
        			this.advisedBeans.put(cacheKey, Boolean.TRUE);
                    
                    //
        			Object proxy = createProxy(
        					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        			this.proxyTypes.put(cacheKey, proxy.getClass());
        			return proxy;
        		}
        
    5. 创建代理对象

      public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
         if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
               throw new AopConfigException("TargetSource cannot determine target class: " +
                     "Either an interface or a target is required for proxy creation.");
            }
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                //JDk动态代理
               return new JdkDynamicAopProxy(config);
            }
             //Cglib动态代理 效率比较高 覆盖子类	
            return new ObjenesisCglibAopProxy(config);
         }
         else {
            return new JdkDynamicAopProxy(config);
         }
      }
      

拦截AOP

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值