16、SpringBoot之AOP创建代理

别说谁变了你拦得住时间么 提交于 2020-02-28 05:55:26

1.1、简介

// 要使用SpringBoot的AOP功能,需要在pom中新增aop依赖
<dependency>  
   <groupid>org.springframework.boot</groupid>  
   <artifactid>spring-boot-starter-aop</artifactid>  
</dependency>

// 引入依赖之后,就不需要在主配置上手动开启AOP功能了,自动配置类会做
@EnableAspectJAutoProxy  
public class SpringbootApplication {
@Service  
public class AopTestService {  
  
    // 要被增强的方法
    public void sayHello(){  
        System.out.println("sayHello");  
    }  
}
// 切面,下面就以这个例子来分析AOP
@Aspect  
@Component  
public class TestAspect {  
  
    @Before("execution(public void com.lwh.springboot.transaction.AopTestService.sayHello(..))")  
    public void doBefore(JoinPoint joinPoint){  
        System.out.println("doBefore run...");  
    }  
}

1.2、创建代理对象

// 下面就分析AopTestService这个bean被创建过程中,AOP在哪里被引入的,怎样创建的代理对象?
// 这边默认已经对SpringBoot初始化单例bean的过程了解了
// 这部分依次走refresh → finishBeanFactoryInitialization → preInstantiateSingletons → getBean → doGetBean → createBean方法
@Override  
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)  
                                                                                throws BeanCreationException {
    // 删除了其余代码,留下两个关键步骤,下面单独分析这两个方法
    // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.  
    // 步骤1) 获取Advisors
    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    // 步骤2) 创建AopTestService实例对象,接着为其创建代理对象
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);

1.2.1、步骤1)

// 给后置处理器一个机会,来生成一个代理对象,代替普通的目标对象,这边不会真正创建代理对象,只是提前做收集工作
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {  
     Object bean = null;  
     if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {  
        // Make sure bean class is actually resolved at this point.
        // 这段源码中先检查是否有InstantiationAwareBeanPostProcessor,这个属性上一篇已经赋值为true
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {  
           Class<?> targetType = determineTargetType(beanName, mbd);  
	   // targetType就是AopTestService
           if (targetType != null) {  
	       // 走这边
               bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);  
               if (bean != null) {  
                  bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);  
               }  
           }  
        }  
        mbd.beforeInstantiationResolved = (bean != null);  
     }  
     return bean;  
}

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {  
     for (BeanPostProcessor bp : getBeanPostProcessors()) {  
         if (bp instanceof InstantiationAwareBeanPostProcessor) {  
             InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;  
	     // 这边走AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation方法
             Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);  
             if (result != null) {  
                return result;  
             }  
         }  
     }  
     return null;  
}
@Override  
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {  
     Object cacheKey = getCacheKey(beanClass, beanName);  
  
     if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {  
	 // 判断该bean有没有已经被增加过了,第一次来走到下面
         if (this.advisedBeans.containsKey(cacheKey)) {  
            return null;  
         }  
	 // 来看这边,第一个判断比较简单,返回false,走到shouldSkip方法,这里面逻辑很重要
         if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {  
            this.advisedBeans.put(cacheKey, Boolean.FALSE);  
            return null;  
	 }  
     }  
    
     // 删除部分代码
     return null;
}
protected boolean shouldSkip(Class<?> beanClass, String beanName) {  
    // TODO: Consider optimization by caching the list of the aspect names  
    // 下面先看第一个步骤
    List<advisor> candidateAdvisors = findCandidateAdvisors();  
    for (Advisor advisor : candidateAdvisors) {  
        if (advisor instanceof AspectJPointcutAdvisor &&  
                                 ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {  
           return true;  
        }  
    }  
    return super.shouldSkip(beanClass, beanName);  
}
@Override  
protected List<advisor> findCandidateAdvisors() {  
    // Add all the Spring advisors found according to superclass rules.  
    // 添加所有根据父类的规则找到的Spring的增强器,这边debug发现找到了一个,是
    // BeanFactoryTransactionAttributeSourceAdvisor,是用于事务管理的
    List<advisor> advisors = super.findCandidateAdvisors();  
    // Build Advisors for all AspectJ aspects in the bean factory.  
    if (this.aspectJAdvisorsBuilder != null) {  
	// 下面看这个,给所有BeanFactory中的AspectJ切面构建增强器
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());  
    }  
    return advisors;  
}
public List<advisor> buildAspectJAdvisors() {  
    // 已经缓存好的,AopTestService进来时发现缓存已经有值了,猜测是前面的bean创建时缓存好了
    List<string> aspectNames = this.aspectBeanNames;  
  
    if (aspectNames == null) {  
        // 没有缓存的话,自己去查找,待会分析,记为a处
    }  
  
    if (aspectNames.isEmpty()) {  
        return Collections.emptyList();  
    }  
    List<advisor> advisors = new ArrayList<>();  
    for (String aspectName : aspectNames) {  
  	// 从缓存中查找并返回
        List<advisor> cachedAdvisors = this.advisorsCache.get(aspectName);  
        if (cachedAdvisors != null) {  
           advisors.addAll(cachedAdvisors);  
        }  
        else { 
	   // 找不到的话自己去查找,和a处一样,也是自己去查找
           MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);  
           advisors.addAll(this.advisorFactory.getAdvisors(factory));  
        }  
     }  
     return advisors;  
}
if (aspectNames == null) {  
    synchronized (this) {  
       aspectNames = this.aspectBeanNames;  
       if (aspectNames == null) {  
           List<advisor> advisors = new ArrayList<>();  
           aspectNames = new ArrayList<>();  
	   // 这边是找出容器中所有的bean
           String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(  
                                                              this.beanFactory, Object.class, true, false);  
           for (String beanName : beanNames) {  
                if (!isEligibleBean(beanName)) {  
                    continue;  
                }  
                Class<?> beanType = this.beanFactory.getType(beanName);  
                if (beanType == null) {  
                   continue;  
                }  
		// 依此遍历这个bean,判断它是不是Aspect
                if (this.advisorFactory.isAspect(beanType)) {  
                   aspectNames.add(beanName);  
                   AspectMetadata amd = new AspectMetadata(beanType, beanName);  
	           // 默认走到这里
                   if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {  
                      MetadataAwareAspectInstanceFactory factory =  
                                                     new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); 
	              // 创建增强器,下面分析这个步骤
                      List<advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);  
		      // 创建完成之后缓存中
                      if (this.beanFactory.isSingleton(beanName)) {  
                         this.advisorsCache.put(beanName, classAdvisors);  
                      }  
                      else {  
                         this.aspectFactoryCache.put(beanName, factory);  
                      }  
                      advisors.addAll(classAdvisors);  
                   }  
                   else { 
                      MetadataAwareAspectInstanceFactory factory =  
                                                    new PrototypeAspectInstanceFactory(this.beanFactory, beanName);  
                      this.aspectFactoryCache.put(beanName, factory);  
                      advisors.addAll(this.advisorFactory.getAdvisors(factory));  
                   }  
                }  
           }  
           this.aspectBeanNames = aspectNames;  
           return advisors;  
       }  
   }  
}
@Override  
public List<advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { 
    // TestAspect
    Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();  
    String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();  
    validate(aspectClass);  
  
    MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =  
                                           new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);  
  
    List<advisor> advisors = new ArrayList<>();
    // 这边去创建增强器,并加入到集合中返回,筛选没有标注@Pointcut注解的方法,并创建增强器
    for (Method method : getAdvisorMethods(aspectClass)) {  
        Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);  
        if (advisor != null) {  
            advisors.add(advisor);  
        }  
    }  
    // 删掉一些方法
    return advisors;  
}
private List<method> getAdvisorMethods(Class<?> aspectClass) {  
    final List<method> methods = new ArrayList<>;();  
    ReflectionUtils.doWithMethods(aspectClass, method -> {  
       // Exclude pointcuts  
       if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {  
           methods.add(method);  
       }  
    });  
    methods.sort(METHOD_COMPARATOR);  
    return methods;  
}
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,  
                                                        int declarationOrderInAspect, String aspectName) {  
    validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());  
    // 解析切入点,下面看这个
    AspectJExpressionPointcut expressionPointcut = getPointcut(  
                                  candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());  
    if (expressionPointcut == null) {  
       return null;  
    }  
    // 将切入点和通知包装成一个切面,method是doBefore
    return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,  
                                                  this, aspectInstanceFactory, declarationOrderInAspect, aspectName);  
}
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {  
    AspectJAnnotation<?> aspectJAnnotation =  
                             AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);  
    if (aspectJAnnotation == null) {  
        return null;  
    }  
  
    AspectJExpressionPointcut ajexp =  
                        new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);  
    ajexp.setExpression(aspectJAnnotation.getPointcutExpression());  
    if (this.beanFactory != null) {  
       ajexp.setBeanFactory(this.beanFactory);  
    }  
    return ajexp;  
}

private static final Class<?>[] ASPECTJ_ANNOTATION_CLASSES = new Class<!--?-->[] {  
         Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class};
	  
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {  
    for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {  
        AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<annotation>) clazz);  
        if (foundAnnotation != null) {  
           return foundAnnotation;  
        }  
    }  
    return null;  
}
// 回到之前的shouldSkip方法
protected boolean shouldSkip(Class<?> beanClass, String beanName) {  
    List<advisor> candidateAdvisors = findCandidateAdvisors();  
    // 这边结束就找到了两个Advisor,一个是处理事务的,一个就是我们的doBefore方法
    for (Advisor advisor : candidateAdvisors) {  
        if (advisor instanceof AspectJPointcutAdvisor &&  
                             ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {  
           return true;  
        }  
    }  
    return super.shouldSkip(beanClass, beanName);  
}
// shouldSkip方法返回false,它结束后,返回null,步骤1就结束了
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

1.2.2、步骤2) doCreateBean

Object beanInstance = doCreateBean(beanName, mbdToUse, args);

// 走到这边,这里对象已经创建完成,接下来属性赋值和后处理
populateBean(beanName, mbd, instanceWrapper);  
exposedObject = initializeBean(beanName, exposedObject, mbd);

// initializeBean中走到这里
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)  
                                                                              throws BeansException {  
     Object result = existingBean;  
     for (BeanPostProcessor processor : getBeanPostProcessors()) {  
         Object current = processor.postProcessAfterInitialization(result, beanName);  
         if (current == null) {  
            return result;  
         }  
         result = current;  
     }  
     return result;  
}
// 走到AbstractAutoProxyCreator的applyBeanPostProcessorsAfterInitialization方法,它是
// AnnotationAwareAspectJAutoProxyCreator的父类
@Override  
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {  
    if (bean != null) {  
       Object cacheKey = getCacheKey(bean.getClass(), beanName);  
       if (this.earlyProxyReferences.remove(cacheKey) != bean) {  
           return wrapIfNecessary(bean, beanName, cacheKey);  
       }  
    }  
    return bean;  
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { 
    // 先获取该类被切的增强器
    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;  
    }  
  
    this.advisedBeans.put(cacheKey, Boolean.FALSE);  
    return bean;  
}
// getAdvicesAndAdvisorsForBean
protected Object[] getAdvicesAndAdvisorsForBean(  
                          Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {  
    // 先看这个方法
    List<advisor> advisors = findEligibleAdvisors(beanClass, beanName);  
    if (advisors.isEmpty()) {  
        return DO_NOT_PROXY;  
    }  
    return advisors.toArray();  
}

protected List<advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { 
    // 这个方法之前已经分析过了,返回两个Advisor
    List<advisor> candidateAdvisors = findCandidateAdvisors();  
    // findAdvisorsThatCanApply方法要过滤出可以代理的增强器,也就是能切该Bean的切面,这部分就是使用切入点表达式与当
    // 前Bean中方法进行匹配,这边就返回一个,就是doBefore方法对应的通知
    List<advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);  
    // 这边再在首部加入一个ExposeInvocationInterceptor
    extendAdvisors(eligibleAdvisors);  
    if (!eligibleAdvisors.isEmpty()) {  
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);  
    }  
    return eligibleAdvisors;  
}
// 再回到wrapIfNecessary方法
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { 
    // 这边已经获取到了
    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;  
    }  
  
    this.advisedBeans.put(cacheKey, Boolean.FALSE);  
    return bean;  
}
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,  
                                     @Nullable Object[] specificInterceptors, TargetSource targetSource) {  
  
    if (this.beanFactory instanceof ConfigurableListableBeanFactory) {  
        AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);  
    }  
    // 创建代理工厂,使用它来创建代理对象
    ProxyFactory proxyFactory = new ProxyFactory();  
    // 从当前执行的AbstractAutoProxyCreator中复制一些配置
    proxyFactory.copyFrom(this);  
  
    if (!proxyFactory.isProxyTargetClass()) {  
        if (shouldProxyTargetClass(beanClass, beanName)) {  
            proxyFactory.setProxyTargetClass(true);  
        }  
        else {  
            evaluateProxyInterfaces(beanClass, proxyFactory);  
        }  
    }  
    // 组合所有增强器
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    // 将增强器放入代理工厂
    proxyFactory.addAdvisors(advisors);  
    proxyFactory.setTargetSource(targetSource);  
    customizeProxyFactory(proxyFactory);  
  
    proxyFactory.setFrozen(this.freezeProxy);  
    if (advisorsPreFiltered()) {  
       proxyFactory.setPreFiltered(true);  
    }  
  
    // 开始创建代理对象
    return proxyFactory.getProxy(getProxyClassLoader());  
}
public Object getProxy(@Nullable ClassLoader classLoader) {  
    // 分两步
    return createAopProxy().getProxy(classLoader);  
}
protected final synchronized AopProxy createAopProxy() {  
    if (!this.active) {  
        activate();  
    }  
    return getAopProxyFactory().createAopProxy(this);  
}
// 如果目标对象有接口,用jdk动态代理. 没有接口,用cglib动态代理
@Override  
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {  
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {  
        Class<?> targetClass = config.getTargetClass();  
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {  
           return new JdkDynamicAopProxy(config);  
        }  
	// AopTestService没有实现接口,走这里
        return new ObjenesisCglibAopProxy(config);  
    }  
    else {  
        return new JdkDynamicAopProxy(config);  
    }  
}
// return createAopProxy().getProxy(classLoader)
// 以JDK代理为例
public Object getProxy(@Nullable ClassLoader classLoader) {
    Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);  
    findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); 
    // 这边就是通过Proxy.newInstance创建代理对象
    return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);  
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!