AOP源码解析之二-创立AOP代理前传,获取AOP信息。
上篇文章对AOP的基本概念说分明了,那么接下来的AOP还剩下两个大的步骤获取定义的AOP信息,生成代理对象扔到beanFactory中。
本篇文章重点对前半部分,如何获取到AOP信息的过程解读。
在Spring的外围办法Refresh办法中,aop是在
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
开始切入的,该文章就开始深刻这个办法进行解析。
@Nullable 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. // hasInstantiationAwareBeanPostProcessors()是来判断容器中是否有InstantiationAwareBeanPostProcessor的实现bean // AOP切面后置处理器AspectJAwareAdvisorAutoProxyCreator就实现了InstantiationAwareBeanPostProcessor接口 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { // 执行实现了InstantiationAwareBeanPostProcessor接口的BeanPostProcessor中的前置解决办法postProcessBeforeInstantiation办法 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { // 执行实现了InstantiationAwareBeanPostProcessor接口的BeanPostProcessor中的后置解决办法postProcessAfterInitialization办法 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }
见名知意,resolveBeforeInstantiation(执行初始化前办法),这一步次要判断一下工厂中是否有 InstantiationAwareBeanPostProcessor 的实现bean。InstantiationAwareBeanPostProcessor 应该是AOP最外围的接口了。
咱们看一下InstantiationAwareBeanPostProcessor 的继承构造。
咱们具体的说下InstantiationAwareBeanPostProcessor 这个接口。
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException; boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException; PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;}
它和 BeanPostProcessor 的办法十分类似,而且它还继承了 BeanPostProcessor。
上面是 BeanPostProcessor 中的两个办法:
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
发现没有,InstantiationAwareBeanPostProcessor 是 Instantiation
,BeanPostProcessor 是 Initialization
,它代表的是 bean 在实例化实现并且属性注入实现,在执行 init-method 的前后进行作用的。
而 InstantiationAwareBeanPostProcessor 的执行机会要后面一些,咱们回到refresh办法的doCreateBean中看一下。
看到这读者想必对于aop的执行机会曾经隐隐约约的心里有个大略了。
咱们定义的盘绕告诉,创立代理肯定是在postProcessBeforeInitialization实现的。
咱们的重点就是看看postProcessBeforeInitialization的办法中的告诉怎么获取,怎么创立代理对象的进行具体的解读。
本文先对前半部分解读。
咱们持续看postProcessBeforeInitialization有哪些实现类。
咱们重点看AbstractAutoProxyCreator的实现类。
@Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); // 1.判断以后bean是否须要被代理,如果须要则进行封装 if (this.earlyProxyReferences.remove(cacheKey) != bean) { //1.判断以后bean是否须要被代理,如果须要则进行封装 return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
如果须要代理执行继wrapIfNecessary办法。
//这个办法将返回代理类 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { // 1.判断以后bean是否在targetSourcedBeans缓存中存在(曾经解决过),如果存在,则间接返回以后bean if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } // 2.在advisedBeans缓存中存在,并且value为false,则代表无需解决 if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } // 3.bean的类是aop基础设施类 || bean应该跳过,则标记为无需解决,并返回 if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. // 4.获取以后bean的Advices和Advisors Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); // 5.如果存在增强器则创立代理 if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); // 创立代理...创立代理...创立代理... // 5.1 创立代理对象:这边SingletonTargetSource的target属性寄存的就是咱们原来的bean实例(也就是被代理对象), // 用于最初减少逻辑执行结束后,通过反射执行咱们真正的办法时应用(method.invoke(bean, args)) Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); // 5.2 创立完代理后,将cacheKey -> 代理类的class放到缓存 this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } // 6.标记为无需解决 this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
4.1 咱们先查看第一条主线,获取以后bean的Advices和Advisors
@Override @Nullable protected Object[] getAdvicesAndAdvisorsForBean( Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) { // 1.找到符合条件的Advisor List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName); if (advisors.isEmpty()) { // 2.如果没有符合条件的Advisor,则返回null return DO_NOT_PROXY; } return advisors.toArray(); }
注:Advisors即是aop的盘绕告诉。
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { // 1.查找所有的候选Advisor List<Advisor> candidateAdvisors = findCandidateAdvisors(); // 2.从所有候选的Advisor中找出符合条件的 List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); // 3.扩大办法,留个子类实现 extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { // 4.对符合条件的Advisor进行排序 eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
这一步所做的事很简略,就是查找所有候选的Advisor,然而调用链路特地的长,如果将这些彻底搞明确,还是须要消耗一番功夫的,读者能够抉择深刻水平。
1、寻找可用的Advisor
public List<Advisor> findAdvisorBeans() { // Determine list of advisor bean names, if not cached already. // 1.确认advisor的beanName列表,优先从缓存中拿 String[] advisorNames = this.cachedAdvisorBeanNames; if (advisorNames == null) { // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the auto-proxy creator apply to them! // 1.1 如果缓存为空,则获取class类型为Advisor的所有bean名称 advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Advisor.class, true, false); this.cachedAdvisorBeanNames = advisorNames; } if (advisorNames.length == 0) { return new ArrayList<>(); } // 2.遍历解决advisorNames List<Advisor> advisors = new ArrayList<>(); for (String name : advisorNames) { if (isEligibleBean(name)) { // 2.1 跳过以后正在创立的advisor if (this.beanFactory.isCurrentlyInCreation(name)) { if (logger.isTraceEnabled()) { logger.trace("Skipping currently created advisor '" + name + "'"); } } else { try { // 2.2 通过beanName获取对应的bean对象,并增加到advisors advisors.add(this.beanFactory.getBean(name, Advisor.class)); } catch (BeanCreationException ex) { Throwable rootCause = ex.getMostSpecificCause(); if (rootCause instanceof BeanCurrentlyInCreationException) { BeanCreationException bce = (BeanCreationException) rootCause; String bceBeanName = bce.getBeanName(); if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) { if (logger.isTraceEnabled()) { logger.trace("Skipping advisor '" + name + "' with dependency on currently created bean: " + ex.getMessage()); } // Ignore: indicates a reference back to the bean we're trying to advise. // We want to find advisors other than the currently created bean itself. continue; } } throw ex; } } } } // 3.返回符合条件的advisor列表 return advisors; }
/** * 找到符合条件的Advisor * @return */@Overrideprotected List<Advisor> findCandidateAdvisors() { // Add all the Spring advisors found according to superclass rules. List<Advisor> advisors = super.findCandidateAdvisors(); // Build Advisors for all AspectJ aspects in the bean factory. if (this.aspectJAdvisorsBuilder != null) { advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } return advisors;}
public List<Advisor> buildAspectJAdvisors() { List<String> aspectNames = this.aspectBeanNames; // 1.如果aspectNames为空,则进行解析 if (aspectNames == null) { synchronized (this) { aspectNames = this.aspectBeanNames; if (aspectNames == null) { List<Advisor> advisors = new ArrayList<>(); aspectNames = new ArrayList<>(); // 1.1 获取所有的beanName String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Object.class, true, false); // 1.2 循环遍历所有的beanName,找出对应的加强办法 for (String beanName : beanNames) { // 1.3 不非法的beanName则跳过,默认返回true,子类能够笼罩实现,AnnotationAwareAspectJAutoProxyCreator // 实现了本人的逻辑,反对应用includePatterns进行筛选 if (!isEligibleBean(beanName)) { continue; } // We must be careful not to instantiate beans eagerly as in this case they // would be cached by the Spring container but would not have been weaved. // 获取beanName对应的bean的类型 Class<?> beanType = this.beanFactory.getType(beanName); if (beanType == null) { continue; } // 1.4 如果beanType存在Aspect注解则进行解决 if (this.advisorFactory.isAspect(beanType)) { // 将存在Aspect注解的beanName增加到aspectNames列表 aspectNames.add(beanName); // 新建切面元数据 AspectMetadata amd = new AspectMetadata(beanType, beanName); if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { // 应用BeanFactory和beanName创立一个BeanFactoryAspectInstanceFactory,次要用来创立切面对象实例 MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); // 1.5 解析标记AspectJ注解中的加强办法********************* List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); // 1.6 放到缓存中 if (this.beanFactory.isSingleton(beanName)) { // 如果beanName是单例则间接将解析的加强办法放到缓存 this.advisorsCache.put(beanName, classAdvisors); } else { // 如果不是单例,则将factory放到缓存,之后能够通过factory来解析加强办法 this.aspectFactoryCache.put(beanName, factory); } // 1.7 将解析的增强器增加到advisors advisors.addAll(classAdvisors); } else { // Per target or per this. if (this.beanFactory.isSingleton(beanName)) { // 名称为beanName的Bean是单例,但切面实例化模型不是单例,则抛异样 throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton"); } MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName); // 将factory放到缓存,之后能够通过factory来解析加强办法 this.aspectFactoryCache.put(beanName, factory); // 解析标记AspectJ注解中的加强办法,并增加到advisors中 advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } } // 1.9 将解析进去的切面beanName放到缓存aspectBeanNames 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)); } } // 1.10 最初返回解析进去的增强器 return advisors;}
@Overridepublic List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { // 1.后面咱们将beanClass和beanName封装成了aspectInstanceFactory的AspectMetadata属性, // 这边能够通过AspectMetadata属性从新获取到以后解决的切面类 Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); // 2.获取以后解决的切面类的名字 String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName(); // 3.校验切面类 validate(aspectClass); // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator // so that it will only instantiate once. // 4.应用装璜器包装MetadataAwareAspectInstanceFactory,以便它只实例化一次。 MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); List<Advisor> advisors = new ArrayList<>(); // 5.获取切面类中的办法(也就是咱们用来进行逻辑加强的办法,被@Around、@After等注解润饰的办法,应用@Pointcut的办法不解决) for (Method method : getAdvisorMethods(aspectClass)) { // 6.解决method,获取增强器 Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); if (advisor != null) { // 7.如果增强器不为空,则增加到advisors advisors.add(advisor); } } // If it's a per target aspect, emit the dummy instantiating aspect. if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { // 8.如果寻找的增强器不为空而且又配置了加强提早初始化,那么须要在首位退出同步实例化增强器(用以保障加强应用之前的实例化) Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); advisors.add(0, instantiationAdvisor); } // Find introduction fields. // 9.获取DeclareParents注解 for (Field field : aspectClass.getDeclaredFields()) { Advisor advisor = getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } } return advisors;}
@Override@Nullablepublic Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) { // 1.校验切面类 validate(aspectInstanceFactory.getAspectMetadata().getAspectClass()); // 2.AspectJ切点信息的获取(例如:表达式),就是指定注解的表达式信息的获取, // 如:@Around("execution(* com.joonwhee.open.aop.*.*(..))") AspectJExpressionPointcut expressionPointcut = getPointcut( candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); // 3.如果expressionPointcut为null,则间接返回null if (expressionPointcut == null) { return null; } // 4.依据切点信息生成增强器 return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName);}
获取到@Before, @Around, @After, @AfterReturning, @AfterThrowing, @Pointcut定义注解信息
@Nullableprivate AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) { // 1.查找并返回给定办法的第一个AspectJ注解(@Before, @Around, @After, @AfterReturning, @AfterThrowing, @Pointcut) // 因为咱们之前把@Pointcut注解的办法跳过了,所以这边必然不会获取到@Pointcut注解 AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); // 2.如果办法没有应用AspectJ的注解,则返回null if (aspectJAnnotation == null) { return null; } // 3.应用AspectJExpressionPointcut实例封装获取的信息 AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]); // 提取失去的注解中的表达式, // 例如:@Around("execution(* com.joonwhee.open.aop.*.*(..))"),失去:execution(* com.joonwhee.open.aop.*.*(..)) ajexp.setExpression(aspectJAnnotation.getPointcutExpression()); if (this.beanFactory != null) { ajexp.setBeanFactory(this.beanFactory); } return ajexp;}
@Nullableprotected 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;}
2、获取切点当前就须要生成增强器了。
new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName)
/** * 依据切点信息生成增强器 * @param declaredPointcut * @param aspectJAdviceMethod * @param aspectJAdvisorFactory * @param aspectInstanceFactory * @param declarationOrder * @param aspectName */public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut, Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { // 1.简略的将信息封装在类的实例中 this.declaredPointcut = declaredPointcut; this.declaringClass = aspectJAdviceMethod.getDeclaringClass(); this.methodName = aspectJAdviceMethod.getName(); this.parameterTypes = aspectJAdviceMethod.getParameterTypes(); // aspectJAdviceMethod保留的是咱们用来进行逻辑加强的办法(@Around、@After等润饰的办法) this.aspectJAdviceMethod = aspectJAdviceMethod; this.aspectJAdvisorFactory = aspectJAdvisorFactory; this.aspectInstanceFactory = aspectInstanceFactory; this.declarationOrder = declarationOrder; this.aspectName = aspectName; // 2.是否须要提早实例化 if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { // Static part of the pointcut is a lazy type. Pointcut preInstantiationPointcut = Pointcuts.union( aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut); // Make it dynamic: must mutate from pre-instantiation to post-instantiation state. // If it's not a dynamic pointcut, it may be optimized out // by the Spring AOP infrastructure after the first evaluation. this.pointcut = new PerTargetInstantiationModelPointcut( this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory); this.lazy = true; } else { // A singleton aspect. this.pointcut = this.declaredPointcut; this.lazy = false; // 3.实例化增强器:依据注解中的信息初始化对应的增强器 this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut); }}
通过以上长长的源码剖析过程,就将aop的第一个大过程,获取到咱们定义的@Before、@After的办法当前,进行加强,下一步就要拿到这些获取的信息去创立代理对象了。