/** * 创建Bean的代理的入口 * Create a proxy with the configured interceptors if the bean is * identified as one to proxy by the subclass. * * @see #getAdvicesAndAdvisorsForBean */ @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { //从缓存中获取代理实例 ObjectcacheKey= getCacheKey(bean.getClass(), beanName); // 1.判断当前bean是否需要被代理,如果需要则进行封装 if (this.earlyProxyReferences.remove(cacheKey) != bean) { //如果需要包装成代理实例 return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
/** * Wrap the given bean if necessary, i.e. if it is eligible for being proxied. * 如果需要包装成代理实例 * * @param bean the raw bean instance * @param beanName the name of the bean * @param cacheKey the cache key for metadata access * @return a proxy wrapping the bean, or the raw bean instance as-is */ 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; }
/** * 查找所有的候选Advisor * @return */ @Override protected List<Advisor> findCandidateAdvisors() { // 1.添加根据父类规则找到的所有advisor。 // 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. //主要看这里,创建候选的切面 // 2.为bean工厂中的所有AspectJ方面构建advisor if (this.aspectJAdvisorsBuilder != null) { advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } return advisors; }
/** * Find all eligible Advisor beans in the current bean factory, * ignoring FactoryBeans and excluding beans that are currently in creation. * 找到当前bean工厂中所有符合条件的Advisor bean, * 忽略FactoryBeans并排除当前正在创建的bean。 * * @return the list of {@link org.springframework.aop.Advisor} beans * @see #isEligibleBean */ 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) { returnnewArrayList<>(); }
List<Advisor> advisors = newArrayList<>(); // 2.遍历处理advisorNames 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) { ThrowablerootCause= ex.getMostSpecificCause(); if (rootCause instanceof BeanCurrentlyInCreationException) { BeanCreationExceptionbce= (BeanCreationException) rootCause; StringbceBeanName= 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; }
/** * Look for AspectJ-annotated aspect beans in the current bean factory, * and return to a list of Spring AOP Advisors representing them. * <p>Creates a Spring Advisor for each AspectJ advice method. * 为bean工厂中的所有AspectJ方面构建advisor * * @return the list of {@link org.springframework.aop.Advisor} beans * @see #isEligibleBean */ 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 = newArrayList<>(); aspectNames = newArrayList<>(); // 1.1 获取spring容器中的所有bean的名称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注解则进行处理 //判断类上是否有@Aspect注解 if (this.advisorFactory.isAspect(beanType)) { // 将存在Aspect注解的beanName添加到aspectNames列表 aspectNames.add(beanName); // 新建切面元数据 AspectMetadataamd=newAspectMetadata(beanType, beanName); // 获取per-clause的类型是SINGLETON if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { // 使用BeanFactory和beanName创建一个BeanFactoryAspectInstanceFactory,主要用来创建切面对象实例 //创建获取有@Aspect注解类的实例工厂,负责获取有@Aspect注解类的实例 MetadataAwareAspectInstanceFactoryfactory= newBeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 1.5 解析标记AspectJ注解中的增强方法 //创建切面advisor对象 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-clause的类型不是SINGLETON // Per target or per this. if (this.beanFactory.isSingleton(beanName)) { // 名称为beanName的Bean是单例,但切面实例化模型不是单例,则抛异常 thrownewIllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton"); } MetadataAwareAspectInstanceFactoryfactory= newPrototypeAspectInstanceFactory(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; // 1.10 最后返回解析出来的增强器 return advisors; } } }
// 4.使用装饰器包装MetadataAwareAspectInstanceFactory,以便它只实例化一次。 //创建工厂的装饰类,获取实例只会获取一次 // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator // so that it will only instantiate once. MetadataAwareAspectInstanceFactorylazySingletonAspectInstanceFactory= newLazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
// If it's a per target aspect, emit the dummy instantiating aspect. if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { // 8.如果寻找的增强器不为空而且又配置了增强延迟初始化,那么需要在首位加入同步实例化增强器(用以保证增强使用之前的实例化) AdvisorinstantiationAdvisor=newSyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); advisors.add(0, instantiationAdvisor); }
// 9.获取DeclareParents注解 //判断属性上是否有引介注解 // Find introduction fields. for (Field field : aspectClass.getDeclaredFields()) { //判断属性上是否有DeclareParents注解,如果有返回切面 Advisoradvisor= getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } }
// 2.是否需要延迟实例化 if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { // Static part of the pointcut is a lazy type. PointcutpreInstantiationPointcut= 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 = newPerTargetInstantiationModelPointcut( this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory); this.lazy = true; } else { // A singleton aspect. this.pointcut = this.declaredPointcut; this.lazy = false; //这个方法重点看看,创建advice对象 // 3.实例化增强器:根据注解中的信息初始化对应的增强器 this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut); } }
// If we get here, we know we have an AspectJ method. // Check that it's an AspectJ-annotated class // 4.如果我们到这里,我们知道我们有一个AspectJ方法。检查切面类是否使用了AspectJ注解 if (!isAspect(candidateAspectClass)) { thrownewAopConfigException("Advice must be declared inside an aspect type: " + "Offending method '" + candidateAdviceMethod + "' in class [" + candidateAspectClass.getName() + "]"); }
if (logger.isDebugEnabled()) { logger.debug("Found AspectJ method: " + candidateAdviceMethod); }
AbstractAspectJAdvice springAdvice;
// 5.根据方法使用的aspectJ注解创建对应的增强器,例如最常见的@Around注解会创建AspectJAroundAdvice //根据不同的注解类型创建不同的advice类实例 switch (aspectJAnnotation.getAnnotationType()) { case AtPointcut: if (logger.isDebugEnabled()) { logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'"); } returnnull; case AtAround: //实现了MethodInterceptor接口 springAdvice = newAspectJAroundAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtBefore: //实现了MethodBeforeAdvice接口,没有实现MethodInterceptor接口 springAdvice = newAspectJMethodBeforeAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtAfter: //实现了MethodInterceptor接口 springAdvice = newAspectJAfterAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtAfterReturning: //实现了AfterReturningAdvice接口,没有实现MethodInterceptor接口 springAdvice = newAspectJAfterReturningAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterReturningafterReturningAnnotation= (AfterReturning) aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterReturningAnnotation.returning())) { springAdvice.setReturningName(afterReturningAnnotation.returning()); } break; case AtAfterThrowing: //实现了MethodInterceptor接口 springAdvice = newAspectJAfterThrowingAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterThrowingafterThrowingAnnotation= (AfterThrowing) aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterThrowingAnnotation.throwing())) { springAdvice.setThrowingName(afterThrowingAnnotation.throwing()); } break; default: thrownewUnsupportedOperationException( "Unsupported advice type on method: " + candidateAdviceMethod); }
// Now to configure the advice... // 6.配置增强器 // 切面类的name,其实就是beanName springAdvice.setAspectName(aspectName); springAdvice.setDeclarationOrder(declarationOrder); // 获取增强方法的参数 String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod); if (argNames != null) { // 如果参数不为空,则赋值给springAdvice springAdvice.setArgumentNamesFromStringArray(argNames); }
@Override public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource()); }
try { // 1.拿到要代理目标类 Class<?> rootClass = this.advised.getTargetClass(); Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Callback[] callbacks = getCallbacks(rootClass); Class<?>[] types = newClass<?>[callbacks.length]; for (intx=0; x < types.length; x++) { types[x] = callbacks[x].getClass(); } // fixedInterceptorMap only populated at this point, after getCallbacks call above // 在上面调用getCallbacks之后,此时仅填充fixedInterceptorMap enhancer.setCallbackFilter(newProxyCallbackFilter( this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance. // 5.生成代理类并创建代理实例,返回代理实例 return createProxyClassAndInstance(enhancer, callbacks); } catch (CodeGenerationException | IllegalArgumentException ex) { thrownewAopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem include using a final class or a non-visible class", ex); } catch (Throwable ex) { // TargetSource.getTarget() failed thrownewAopConfigException("Unexpected AOP exception", ex); } }
private Callback[] getCallbacks(Class<?> rootClass) throws Exception { // Parameters used for optimization choices... // 1.用于优化选择的参数 booleanexposeProxy=this.advised.isExposeProxy(); booleanisFrozen=this.advised.isFrozen(); booleanisStatic=this.advised.getTargetSource().isStatic();
// Choose an "aop" interceptor (used for AOP calls). // 2.使用AdvisedSupport作为参数,创建一个DynamicAdvisedInterceptor(“aop”拦截器,用于AOP调用) // this.advised就是之前创建CglibAopProxy时传进来的ProxyFactory(ProxyCreatorSupport子类) CallbackaopInterceptor=newDynamicAdvisedInterceptor(this.advised);
// Choose a "straight to target" interceptor. (used for calls that are // unadvised but can return this). May be required to expose the proxy. Callback targetInterceptor; if (exposeProxy) { targetInterceptor = (isStatic ? newStaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) : newDynamicUnadvisedExposedInterceptor(this.advised.getTargetSource())); } else { targetInterceptor = (isStatic ? newStaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) : newDynamicUnadvisedInterceptor(this.advised.getTargetSource())); }
// Choose a "direct to target" dispatcher (used for // unadvised calls to static targets that cannot return this). CallbacktargetDispatcher= (isStatic ? newStaticDispatcher(this.advised.getTargetSource().getTarget()) : newSerializableNoOp());
// 3.将aop拦截器添加到mainCallbacks中 Callback[] mainCallbacks = newCallback[] { aopInterceptor, // for normal advice targetInterceptor, // invoke target without considering advice, if optimized newSerializableNoOp(), // no override for methods mapped to this targetDispatcher, this.advisedDispatcher, newEqualsInterceptor(this.advised), newHashCodeInterceptor(this.advised) };
Callback[] callbacks;
// If the target is a static one and the advice chain is frozen, // then we can make some optimizations by sending the AOP calls // direct to the target using the fixed chain for that method. if (isStatic && isFrozen) { Method[] methods = rootClass.getMethods(); Callback[] fixedCallbacks = newCallback[methods.length]; this.fixedInterceptorMap = newHashMap<>(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice) for (intx=0; x < methods.length; x++) { Methodmethod= methods[x]; List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass); fixedCallbacks[x] = newFixedChainStaticTargetInterceptor( chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass()); this.fixedInterceptorMap.put(method, x); }
// Now copy both the callbacks from mainCallbacks // and fixedCallbacks into the callbacks array. callbacks = newCallback[mainCallbacks.length + fixedCallbacks.length]; System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length); System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length); this.fixedInterceptorOffset = mainCallbacks.length; } else { callbacks = mainCallbacks; } return callbacks; }