前言
上一篇文章动态AOP自定义标签讲解了自定义配置完成了对AnnotationAwareAspectJAutoProxyCreator类型的自动注册,那么这个类型到底做了什么工作来完成AOP的操作呢?来看一下AnnotationAwareAspectJAutoProxyCreator类UML图:
从上图的类图中可以看出,AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor接口,而实现了BeanPostProcessor后,当Spring加载这个bean时会在实例化前调用其postProcessAfterInitialization方法,而对于AOP的分析也由此开始。
创建AOP代理
在父类AbstractAutoProxyCreator的postProcessAfterInitialization中代码如下:
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { //根据给定的bean的class和name构造作为key,格式为:beanClassName_beanName Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { //如果适合做代理,则需要做封装 return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { //如果已经处理过 if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } //无须增强 if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } //给定的bean类是否代表一个基础的设施类,基础设施类不应代理,或者配置了指定的bean不需要自动代理 if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } //如果存在增强方法则创建代理 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; }
函数中我们已经看到了代理的雏形。当然,在真正开始之前还需要经过一些判断,比如是否已经处理过或者是否需要跳过的bean,而真正创建代理的代码是从getAdvicesAndAdvisorsForBean开始的。
创建代理主要包含了两个步骤:
(1)获取增强方法或者增强器;
(2)根据获取的增强进行代理;
虽然上述步骤看似简单,但是每个步骤中都经历了大量的复杂的逻辑。首先来看看获取增强方法的实现逻辑:
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) { List<Advisor> candidateAdvisors = findCandidateAdvisors(); List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
对于指定bean的增强方法的获取一定是包含两个步骤的,获取所有的增强以及寻找所有增强中适用于bean的增强并应用,那么findCandidateAdvisors和findAdvisorsThatCanApply便是做这两件事情。当然,如果无法找到对应的增强器便返回DO_NOT_PROXY,其中DO_NOT_PROXY = null。
获取增强器
由于我们分析的是使用注解进行的AOP,所以对于findCandidateAdvisors的实现其实是由AnnotationAwareAspectJAutoProxyCreator类完成的,我们继续跟踪AnnotationAwareAspectJAutoProxyCreator的findCandidateAdvisors方法:
protected List<Advisor> findCandidateAdvisors() { //当使用注解方式配置AOP的时候并不是丢弃了对XML配置的支持,在这里调用父类方法加载配置文件中的AOP声明 List<Advisor> advisors = super.findCandidateAdvisors(); //为bean工厂中的所有AspectJ方面构建Advisor if (this.aspectJAdvisorsBuilder != null) { advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } return advisors; }
AnnotationAwareAspectJAutoProxyCreator间接的继承了AbstractAdvisorAutoProxyCreator,在实现获取增强的方法中除了保留父类的获取配置文件中定义的增强外,同时添加了获取bean的注解增强的功能,那么其实现正是由this.aspectJAdvisorsBuilder.buildAspectJAdvisors()来实现的。
public List<Advisor> buildAspectJAdvisors() { List<String> aspectNames = this.aspectBeanNames; if (aspectNames == null) { synchronized (this) { aspectNames = this.aspectBeanNames; if (aspectNames == null) { List<Advisor> advisors = new ArrayList<>(); aspectNames = new ArrayList<>(); //获取所有的beanName String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Object.class, true, false); //循环所有beanName找出对应的增强方法 for (String beanName : beanNames) { //不合法的bean则略过,由子类定义规则,默认返回true if (!isEligibleBean(beanName)) { continue; } // 获取对应的bean类型 Class<?> beanType = this.beanFactory.getType(beanName); if (beanType == null) { continue; } //判断是否存在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); //解析标记AspectJ注解中的增强方法 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 { if (this.beanFactory.isSingleton(beanName)) { throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton"); } MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName); this.aspectFactoryCache.put(beanName, factory); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } } this.aspectBeanNames = aspectNames; return advisors; } } } 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 { MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } return advisors; }