Spring Framework版本:5.2.8.RELEASE。
因为Spring AOP依赖于IoC容器来管理,所以需要首先来掌握Spring IoC的实现(《较真儿学源码系列-Spring IoC核心流程源码分析》)。
AOP(Aspect Oriented Programming),即面向切面编程。指的是在原有的代码基础之上,又包装了一层。使得可以在方法前后、抛出异常、正常返回等时机点做自定义的增强处理,让代码有一种横向进行统一处理的能力。AOP可以有很多的实现场景,包括常见的日志记录、权限验证和异常处理等。我在之前的公司项目中也曾经用Spring AOP来封装了图数据库Neo4j的事务。用了环绕通知和自定义注解,不仅去掉了冗余的try-catch写法,还解决了嵌套事务导致性能低下的问题。
切面就是在一个怎样的环境中工作。比如数据库的事务直接贯穿了整个代码层面,这就是一个切面,它可以定义后面需要介绍的各类通知、切点等内容,然后Spring AOP会将其定义的内容织入到约定的流程中,在动态代理中可以把它理解成一个拦截器。具体表现是一个使用了@Aspect注解的类就被称为一个切面。
连接点对应的是具体需要增强的东西,比如通过切点表达式去判断哪些方法是连接点,从而织入对应的通知。
目标对象指的是要被增强的对象,也就是包含连接点的对象。
通知是切面开启后、切面的方法。它根据在代理对象真实方法调用前后的顺序和逻辑区分。
前置通知(before):在调用原有对象方法前执行的通知功能。后置通知(after):在调用原有对象方法后执行的通知功能。无论是否抛出异常,它都会被执行。返回通知(afterReturning):在调用原有对象方法后正常返回(无异常)执行的通知功能。异常通知(afterThrowing):在调用原有对象方法产生异常后执行的通知功能。环绕通知(around):相当于前四种通知的整合,当然也可以取代当前被拦截对象的方法。这是一个告诉AOP在什么时候启动拦截并织入对应的流程,因为并不是所有的开发都需要启动AOP的,所以可以通过切点表达式或自定义注解来进行限定。
将通知切入连接点的过程叫织入。
实际上Advisor并不是AOP的术语之一,但却是Spring AOP源码中的内部概念。Advisor是通知和切点的整合,用来管理它们。后面的源码分析中会看到这点。
Spring AOP是AOP在Spring中的实现,而提到AOP就不得不提AspectJ。AspectJ框架来自于Eclipse基金会,不同于Spring AOP是通过动态代理来实现的(JDK动态代理或CGLIB代理),AspectJ是通过静态织入的方式来实现(编译期织入、编译后织入和类加载期织入)。所以在代码运行前就完成了织入,性能要更高。除此之外AspectJ还能干很多Spring AOP不能干的事,是一个很强大的AOP框架。但这并不意味着Spring AOP就一无是处了,Spring AOP致力于解决企业级开发中最普遍遇到的AOP需求,而不是像AspectJ一样成为一个提供最完整AOP实现的框架。
Spring AOP沿用了AspectJ中的一些概念(切点表达式以及通知注解),但实现是Spring AOP自己实现的。
开启AOP需要添加@EnableAspectJAutoProxy注解,那么首先就来看一下其实现:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy { boolean proxyTargetClass() default false; boolean exposeProxy() default false; }可以看到第4行代码处@Import了一个类:AspectJAutoProxyRegistrar。继续来看一下它的实现:
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //注册internalAutoProxyCreator这个bean定义 AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class); if (enableAspectJAutoProxy != null) { //添加proxyTargetClass属性值为true if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } //添加exposeProxy属性值为true if (enableAspectJAutoProxy.getBoolean("exposeProxy")) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } } }可以看到AspectJAutoProxyRegistrar类中只有一个方法:registerBeanDefinitions。那么它是什么时候被调用的呢?结合之前对Spring IoC的分析可知,完整的调用链:<init>(AnnotationConfigApplicationContext)->refresh(AbstractApplicationContext)->invokeBeanFactoryPostProcessors(AbstractApplicationContext)->invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate)->invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate)->postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor)->processConfigBeanDefinitions(ConfigurationClassPostProcessor)->loadBeanDefinitions(ConfigurationClassBeanDefinitionReader)->loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader)->loadBeanDefinitionsFromRegistrars(ConfigurationClassBeanDefinitionReader)->registerBeanDefinitions(ImportBeanDefinitionRegistrar)->registerBeanDefinitions(AspectJAutoProxyRegistrar)
继续来看registerBeanDefinitions方法的实现,第8行代码处会调用registerAspectJAnnotationAutoProxyCreatorIfNecessary方法:
/** * AopConfigUtils: */ @Nullable public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) { return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null); } @Nullable public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary( BeanDefinitionRegistry registry, @Nullable Object source) { return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); } @Nullable private static BeanDefinition registerOrEscalateApcAsRequired( Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); /* 只是开启AOP而没开启事务的话,是不会走入到下面的if条件中来的 这个if条件我会留在之后对事务源码进行分析的文章中进行说明 */ if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); if (!cls.getName().equals(apcDefinition.getBeanClassName())) { int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); int requiredPriority = findPriorityForClass(cls); if (currentPriority < requiredPriority) { apcDefinition.setBeanClassName(cls.getName()); } } return null; } /* 如果此时没有AUTO_PROXY_CREATOR_BEAN_NAME这个bean定义, 就往容器中注册AnnotationAwareAspectJAutoProxyCreator这个bean定义 */ RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }在上面第13行代码处注册了AnnotationAwareAspectJAutoProxyCreator,下面来看一下其继承图:
可以看到,AnnotationAwareAspectJAutoProxyCreator本质上就是一个BeanPostProcessor。同时因为实现了InstantiationAwareBeanPostProcessor接口,所以可以调用其postProcessBeforeInstantiation方法,缓存切面信息。
之前我在分析Spring IoC的源码文章中说过,正常情况下创建AOP对象是在postProcessAfterInitialization方法中创建的,而在循环依赖时则改为了在getEarlyBeanReference方法中创建。postProcessAfterInitialization是BeanPostProcessor中的方法,这就不多说了;同时AnnotationAwareAspectJAutoProxyCreator还实现了SmartInstantiationAwareBeanPostProcessor接口,所以getEarlyBeanReference方法也是可以调用到的了。
下面就来分别看一下这几个方法的实现。
完整的调用链:<init>(AnnotationConfigApplicationContext)->refresh(AbstractApplicationContext)->finishBeanFactoryInitialization(AbstractApplicationContext)->preInstantiateSingletons(DefaultListableBeanFactory)->getBean(AbstractBeanFactory)->doGetBean(AbstractBeanFactory)->getSingleton(DefaultSingletonBeanRegistry)->getObject(AbstractBeanFactory)->createBean(AbstractAutowireCapableBeanFactory)->resolveBeforeInstantiation(AbstractAutowireCapableBeanFactory)->applyBeanPostProcessorsBeforeInstantiation(AbstractAutowireCapableBeanFactory)->postProcessBeforeInstantiation(AbstractAutoProxyCreator)
/** * AbstractAutoProxyCreator: */ @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) { //构建缓存key Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { //如果已经解析过,就直接返回 if (this.advisedBeans.containsKey(cacheKey)) { return null; } //判断是不是基础的bean,或者应不应该跳过 if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { //如果属于上面的条件之一,就将其设置为不需要代理的 this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } /* 获取自定义的TargetSource,如果有的话,就会创建代理对象(除非容器中有TargetSourceCreator, 并且实现了TargetSource接口,否则一般情况下不会获取到的) */ TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } Object[] specificInterceptors = (beanClass, beanName, targetSource); //创建AOP代理对象 Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } return null; } /** * 第7行代码处: */ protected Object getCacheKey(Class<?> beanClass, @Nullable String beanName) { if (StringUtils.hasLength(beanName)) { //如果是FactoryBean的话,就加上“&”前缀 return (FactoryBean.class.isAssignableFrom(beanClass) ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName); } else { //如果beanName为空的话,就返回beanClass return beanClass; } } /** * AnnotationAwareAspectJAutoProxyCreator: * 第15行代码处: */ @Override protected boolean isInfrastructureClass(Class<?> beanClass) { //判断是不是基础的bean,或者是不是切面 return (super.isInfrastructureClass(beanClass) || (this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass))); } /** * AbstractAutoProxyCreator: * 第62行代码处: */ protected boolean isInfrastructureClass(Class<?> beanClass) { //Advice、Pointcut、Advisor和AopInfrastructureBean被视为基础类 boolean retVal = Advice.class.isAssignableFrom(beanClass) || Pointcut.class.isAssignableFrom(beanClass) || Advisor.class.isAssignableFrom(beanClass) || AopInfrastructureBean.class.isAssignableFrom(beanClass); if (retVal && logger.isTraceEnabled()) { logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]"); } return retVal; } /** * AbstractAspectJAdvisorFactory: * 第63行代码处: */ @Override public boolean isAspect(Class<?> clazz) { //是否有切面注解,并且不是由AspectJ编译的(AspectJ编程中有很多的“ajc$”前缀,以此来进行判断) return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz)); } private boolean hasAspectAnnotation(Class<?> clazz) { //类上面是否含有@Aspect注解 return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null); } /** * AspectJAwareAdvisorAutoProxyCreator: * 第15行代码处: */ @Override protected boolean shouldSkip(Class<?> beanClass, String beanName) { //找到候选的Advisor List<Advisor> candidateAdvisors = findCandidateAdvisors(); for (Advisor advisor : candidateAdvisors) { //如果Advisor是AspectJPointcutAdvisor类型的(XML),并且名称和给定的beanName是一致的,就是需要跳过的 if (advisor instanceof AspectJPointcutAdvisor && ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) { return true; } } //返回false return super.shouldSkip(beanClass, beanName); } /** * AnnotationAwareAspectJAutoProxyCreator: * 第104行代码处: */ @Override protected List<Advisor> findCandidateAdvisors() { //找到事务相关的Advisor(当前没有事务操作,所以在这里会找不到) List<Advisor> advisors = super.findCandidateAdvisors(); if (this.aspectJAdvisorsBuilder != null) { //构建切面Advisor advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } return advisors; } /** * BeanFactoryAspectJAdvisorsBuilder * 第126行代码处: */ public List<Advisor> buildAspectJAdvisors() { //获取缓存中的切面名称 List<String> aspectNames = this.aspectBeanNames; //如果没有获取到 if (aspectNames == null) { synchronized (this) { //双重检查 aspectNames = this.aspectBeanNames; if (aspectNames == null) { //保存解析出来的Advisor集合 List<Advisor> advisors = new ArrayList<>(); aspectNames = new ArrayList<>(); //因为传入的是Object,所以这里是在容器中获取所有的bean名称 String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Object.class, true, false); for (String beanName : beanNames) { //判断bean是否是合适的 if (!isEligibleBean(beanName)) { continue; } //通过bean名称来获取到相应的bean类型 Class<?> beanType = this.beanFactory.getType(beanName); if (beanType == null) { continue; } //判断bean是不是切面 if (this.advisorFactory.isAspect(beanType)) { //如果是的话就加入到aspectNames集合中 aspectNames.add(beanName); AspectMetadata amd = new AspectMetadata(beanType, beanName); if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { //构建切面的实例工厂 MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); //获取Advisor集合 List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); /* 加入到缓存中(如果是单例就放进advisorsCache缓存中,否则就放进aspectFactoryCache缓存中) 因为在上面第150行代码处是从容器中获取所有的bean名称,然后再逐个进行解析的,这个消耗是很大的 (如果bean很多的话),所以解析完是需要放入到缓存中的,以此来提高效率 */ if (this.beanFactory.isSingleton(beanName)) { this.advisorsCache.put(beanName, classAdvisors); } else { this.aspectFactoryCache.put(beanName, factory); } //添加进advisors集合中 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); //加入到aspectFactoryCache缓存中 this.aspectFactoryCache.put(beanName, factory); //获取Advisor集合,并添加进advisors集合中 advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } } //给this.aspectBeanNames进行赋值,下次就不会进行重复解析了 this.aspectBeanNames = aspectNames; return advisors; } } } if (aspectNames.isEmpty()) { return Collections.emptyList(); } List<Advisor> advisors = new ArrayList<>(); //把advisorsCache和aspectFactoryCache缓存融合进一个advisors集合中并最终返回 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; } /** * ReflectiveAspectJAdvisorFactory: * 第171行、第195行和第217行代码处: */ @Override public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { //获取切面类 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, 0, aspectName); if (advisor != null) { advisors.add(advisor); } } //如果需要延迟初始化,就加入一个SyntheticInstantiationAdvisor if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); advisors.add(0, instantiationAdvisor); } //如果有@DeclareParents注解,就加入一个DeclareParentsAdvisor for (Field field : aspectClass.getDeclaredFields()) { Advisor advisor = getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } } return advisors; } /** * 第240行代码处: */ private List<Method> getAdvisorMethods(Class<?> aspectClass) { final List<Method> methods = new ArrayList<>(); ReflectionUtils.doWithMethods(aspectClass, method -> { //排除被@Pointcut注解标注的方法 if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) { methods.add(method); } }, ReflectionUtils.USER_DECLARED_METHODS); if (methods.size() > 1) { /* 对方法进行排序(后面会看到AOP是通过责任链的方式来实现的,所以必须要进行排序,否则逻辑会有问题) 会按照@Around->@Before->@After->@AfterReturning->@AfterThrowing这个顺序进行排序 */ methods.sort(METHOD_COMPARATOR); } return methods; } /** * ReflectionUtils: * 第270行代码处: */ public static void doWithMethods(Class<?> clazz, MethodCallback mc, @Nullable MethodFilter mf) { //根据class类型获取到相应的所有方法 Method[] methods = getDeclaredMethods(clazz, false); for (Method method : methods) { if (mf != null && !mf.matches(method)) { continue; } try { //回调doWith方法 mc.doWith(method); } catch (IllegalAccessException ex) { throw new IllegalStateException("Not allowed to access method '" + method.getName() + "': " + ex); } } if (clazz.getSuperclass() != null && (mf != USER_DECLARED_METHODS || clazz.getSuperclass() != Object.class)) { //处理父类 doWithMethods(clazz.getSuperclass(), mc, mf); } else if (clazz.isInterface()) { //处理接口 for (Class<?> superIfc : clazz.getInterfaces()) { doWithMethods(superIfc, mc, mf); } } } /** * ReflectiveAspectJAdvisorFactory: * 第242行代码处: */ @Override @Nullable 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; } //实例化一个切点Advisor实现类 return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName); } /** * InstantiationModelAwarePointcutAdvisorImpl: */ public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut, Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { //进行属性赋值 this.declaredPointcut = declaredPointcut; this.declaringClass = aspectJAdviceMethod.getDeclaringClass(); this.methodName = aspectJAdviceMethod.getName(); this.parameterTypes = aspectJAdviceMethod.getParameterTypes(); this.aspectJAdviceMethod = aspectJAdviceMethod; this.aspectJAdvisorFactory = aspectJAdvisorFactory; this.aspectInstanceFactory = aspectInstanceFactory; this.declarationOrder = declarationOrder; this.aspectName = aspectName; //判断当前的切面对象是否需要延迟实例化 if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Pointcut preInstantiationPointcut = Pointcuts.union( aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut); this.pointcut = new InstantiationModelAwarePointcutAdvisorImpl.PerTargetInstantiationModelPointcut( this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory); this.lazy = true; } else { this.pointcut = this.declaredPointcut; this.lazy = false; //实例化Advice对象 this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut); } } private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) { Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName); return (advice != null ? advice : EMPTY_ADVICE); } /** * ReflectiveAspectJAdvisorFactory: * 第373行代码处: */ @Override @Nullable public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { //获取切面类Class对象 Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); validate(candidateAspectClass); //获取切面方法上的注解 AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); if (aspectJAnnotation == null) { return null; } //判断是否是切面类 if (!isAspect(candidateAspectClass)) { throw new AopConfigException("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; //获取方法上的注解 switch (aspectJAnnotation.getAnnotationType()) { case AtPointcut: //如果是@Pointcut注解,就直接返回null,因为在之前第272行代码处已经排除了@Pointcut注解标注的方法 if (logger.isDebugEnabled()) { logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'"); } return null; case AtAround: //如果是@Around注解,构建AspectJAroundAdvice springAdvice = new AspectJAroundAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtBefore: //如果是@Before注解,构建AspectJMethodBeforeAdvice springAdvice = new AspectJMethodBeforeAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtAfter: //如果是@After注解,构建AspectJAfterAdvice springAdvice = new AspectJAfterAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtAfterReturning: //如果是@AfterReturning注解,构建AspectJAfterReturningAdvice springAdvice = new AspectJAfterReturningAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterReturningAnnotation.returning())) { springAdvice.setReturningName(afterReturningAnnotation.returning()); } break; case AtAfterThrowing: //如果是@AfterThrowing注解,构建AspectJAfterThrowingAdvice springAdvice = new AspectJAfterThrowingAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterThrowingAnnotation.throwing())) { springAdvice.setThrowingName(afterThrowingAnnotation.throwing()); } break; default: throw new UnsupportedOperationException( "Unsupported advice type on method: " + candidateAdviceMethod); } //配置Advice属性 springAdvice.setAspectName(aspectName); springAdvice.setDeclarationOrder(declarationOrder); String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod); if (argNames != null) { springAdvice.setArgumentNamesFromStringArray(argNames); } springAdvice.calculateArgumentBindings(); return springAdvice; } /** * AbstractAspectJAdvisorFactory: * 第393行代码处: */ @SuppressWarnings("unchecked") @Nullable protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) { /* 获取切面方法上的注解,找到一个就直接返回(ASPECTJ_ANNOTATION_CLASSES包含 @Pointcut、@Around、@Before、@After、@AfterReturning和@AfterThrowing注解) */ for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) { AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz); if (foundAnnotation != null) { return foundAnnotation; } } return null; }再次强调一下:如果是在正常的情况下,创建AOP对象是在initializeBean方法中的applyBeanPostProcessorsAfterInitialization方法中进行的;而如果有循环依赖的话,创建AOP对象则是放在了getEarlyBeanReference方法中。
正常情况下的调用链:<init>(AnnotationConfigApplicationContext)->refresh(AbstractApplicationContext)->finishBeanFactoryInitialization(AbstractApplicationContext)->preInstantiateSingletons(DefaultListableBeanFactory)->getBean(AbstractBeanFactory)->doGetBean(AbstractBeanFactory)->getSingleton(DefaultSingletonBeanRegistry)->getObject(AbstractBeanFactory)->createBean(AbstractAutowireCapableBeanFactory)->doCreateBean(AbstractAutowireCapableBeanFactory)->initializeBean(AbstractAutowireCapableBeanFactory)->applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory)->postProcessAfterInitialization(AbstractAutoProxyCreator)
循环依赖时的调用链:<init>(AnnotationConfigApplicationContext)->refresh(AbstractApplicationContext)->finishBeanFactoryInitialization(AbstractApplicationContext)->preInstantiateSingletons(DefaultListableBeanFactory)->getBean(AbstractBeanFactory)->(省略中间循环依赖的过程,直接跳到第二次调用同一个bean的时候)->getBean(AbstractBeanFactory)->doGetBean(AbstractBeanFactory)->getSingleton(DefaultSingletonBeanRegistry)->getSingleton(DefaultSingletonBeanRegistry)->getObject(AbstractAutowireCapableBeanFactory)->getEarlyBeanReference(AbstractAutowireCapableBeanFactory)->getEarlyBeanReference(AbstractAutoProxyCreator)(注:其中红色表示的是重载方法)
/** * AbstractAutoProxyCreator: * 正常情况下 */ @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { //构建缓存key Object cacheKey = getCacheKey(bean.getClass(), beanName); /* 因为循环依赖时会在下面的getEarlyBeanReference方法中创建AOP对象,而该方法会往earlyProxyReferences集合中 放入cacheKey。所以在正常情况下也就是本方法中,此时已经不是循环依赖了,就需要remove掉。remove的结果不等于bean, 说明此时earlyProxyReferences集合中没有当前bean;而如果相等,就没有必要调用wrapIfNecessary方法了,因为肯定 已经在getEarlyBeanReference方法中调用过了 */ if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; } /** * 循环依赖时 */ @Override public Object getEarlyBeanReference(Object bean, String beanName) { //构建缓存key Object cacheKey = getCacheKey(bean.getClass(), beanName); //往earlyProxyReferences集合中放入当前cacheKey this.earlyProxyReferences.put(cacheKey, bean); return wrapIfNecessary(bean, beanName, cacheKey); } /** * 第17行和第32行代码处: */ 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; } /* 这里会再次调用isInfrastructureClass和shouldSkip方法来判断是不是基础的bean,或者是不是需要跳过的 (其中会再次走进findCandidateAdvisors->buildAspectJAdvisors方法中,但这次不会再重新解析了, 因为aspectBeanNames缓存中已经有值了) */ if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { //如果属于上面的条件之一,就将其设置为不需要代理的 this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } //找到合适的Advisors Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { //需要代理就设置成TRUE this.advisedBeans.put(cacheKey, Boolean.TRUE); //创建AOP代理对象 Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); //放入到缓存中 this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } //如果不需要代理,就设置成FALSE this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } /** * AbstractAdvisorAutoProxyCreator: * 第59行代码处: */ @Override @Nullable protected Object[] getAdvicesAndAdvisorsForBean( Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) { //找到合适的Advisor List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName); //如果没找到就返回DO_NOT_PROXY if (advisors.isEmpty()) { return DO_NOT_PROXY; } //否则就返回找到的Advisor return advisors.toArray(); } /** * 第86行代码处: */ protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { /* 这里和上面一样,也会调用findCandidateAdvisors方法,以此来寻找缓存中的候选Advisor集合 但因为之前已经缓存了,所以这里不用再解析一遍了 */ List<Advisor> candidateAdvisors = findCandidateAdvisors(); //从候选的Advisor集合中找出能匹配的上切点的Advisor List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); //在Advisor集合中添加一个内置的Advisor(ExposeInvocationInterceptor) extendAdvisors(eligibleAdvisors); //这里又会再一次对Advisor进行排序 if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; } /** * 第105行代码处: */ protected List<Advisor> findAdvisorsThatCanApply( List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) { //用来记录当前代理Bean的名称 ProxyCreationContext.setCurrentProxiedBeanName(beanName); try { //从候选的Advisor中找出能匹配的上切点的Advisor return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); } finally { //清除当前代理Bean的名称 ProxyCreationContext.setCurrentProxiedBeanName(null); } } /** * AopUtils: * 第125行代码处: */ public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { //如果候选的Advisor为空,就直接返回 if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List<Advisor> eligibleAdvisors = new ArrayList<>(); for (Advisor candidate : candidateAdvisors) { /* 如果候选的Advisor是IntroductionAdvisor类型的(@DeclareParents),并且能匹配的上切点的话, 就添加进eligibleAdvisors集合中 */ if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { eligibleAdvisors.add(candidate); } } boolean hasIntroductions = !eligibleAdvisors.isEmpty(); for (Advisor candidate : candidateAdvisors) { //如果候选的Advisor是IntroductionAdvisor类型的 if (candidate instanceof IntroductionAdvisor) { //在上面已经处理过了,这里不需要再处理 continue; } /* 如果候选的Advisor不是IntroductionAdvisor类型的,也去判断是否能匹配的上切点 如果能就也添加进eligibleAdvisors集合中 */ if (canApply(candidate, clazz, hasIntroductions)) { eligibleAdvisors.add(candidate); } } return eligibleAdvisors; } /** * 第147行代码处: */ public static boolean canApply(Advisor advisor, Class<?> targetClass) { return canApply(advisor, targetClass, false); } /** * 第162行和第173行代码处: */ public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) { if (advisor instanceof IntroductionAdvisor) { //如果Advisor是IntroductionAdvisor类型的,就使用它的方法来查看是否匹配切点 return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass); } else if (advisor instanceof PointcutAdvisor) { //如果Advisor是PointcutAdvisor类型的,就进行强转 PointcutAdvisor pca = (PointcutAdvisor) advisor; //并且判断是否能真正匹配上切点 return canApply(pca.getPointcut(), targetClass, hasIntroductions); } else { //没有切入点就假设它能用 return true; } } /** * 第187行代码处: */ public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) { Assert.notNull(pc, "Pointcut must not be null"); //查看是否匹配切点,如果不匹配,就直接返回false if (!pc.getClassFilter().matches(targetClass)) { return false; } //获取方法匹配器 MethodMatcher methodMatcher = pc.getMethodMatcher(); if (methodMatcher == MethodMatcher.TRUE) { return true; } //判断方法匹配器是不是IntroductionAwareMethodMatcher类型的,如果是就进行强转 IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null; if (methodMatcher instanceof IntroductionAwareMethodMatcher) { introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher; } Set<Class<?>> classes = new LinkedHashSet<>(); //判断当前Class是否是动态生成的目标类,如果不是的话 if (!Proxy.isProxyClass(targetClass)) { //添加当前Class进classes集合中,如果是CGLIB生成的子类,则添加其父类进classes集合中 classes.add(ClassUtils.getUserClass(targetClass)); } //添加当前Class所实现的所有接口进classes集合中 classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); for (Class<?> clazz : classes) { //获取到classes集合中每一个class中的所有方法 Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz); for (Method method : methods) { //通过方法匹配器进行匹配(匹配成功一个就直接返回true) if (introductionAwareMethodMatcher != null ? introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) : methodMatcher.matches(method, targetClass)) { return true; } } } return false; } /** * AbstractAutoProxyCreator * 第64行代码处: */ protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { //如果当前容器是ConfigurableListableBeanFactory类型的,就设置originalTargetClass属性 AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } //创建一个代理工厂 ProxyFactory proxyFactory = new ProxyFactory(); //复制配置属性 proxyFactory.copyFrom(this); //如果@EnableAspectJAutoProxy注解中的proxyTargetClass属性为false(为false代表JDK动态代理) if (!proxyFactory.isProxyTargetClass()) { //检查bean定义的preserveTargetClass属性值是否为true if (shouldProxyTargetClass(beanClass, beanName)) { //如果为true就设置代理工厂的proxyTargetClass属性为true proxyFactory.setProxyTargetClass(true); } else { /* 否则就将bean上实现的接口应用于proxyFactory上(如果要代理的类没有接口的话, 即使proxyTargetClass为false,也会在这里被修正为true) */ evaluateProxyInterfaces(beanClass, proxyFactory); } } //构建Advisor的集合(包含上面找到的能匹配上切点的Advisor以及通用拦截器) Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); //代理工厂加上这些Advisor proxyFactory.addAdvisors(advisors); //代理工厂设置TargetSource proxyFactory.setTargetSource(targetSource); //空实现,提供干预点 customizeProxyFactory(proxyFactory); //此时冻结配置 proxyFactory.setFrozen(this.freezeProxy); //是否预先筛选,如果是的话就将该属性设置进代理工厂里 if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } //这里是在真正地创建代理对象 return proxyFactory.getProxy(getProxyClassLoader()); } /** * ProxyFactory: */ public Object getProxy(@Nullable ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); } /** * ProxyCreatorSupport: */ protected final synchronized AopProxy createAopProxy() { if (!this.active) { //激活代理配置 activate(); } return getAopProxyFactory().createAopProxy(this); } /** * DefaultAopProxyFactory: * 有接口 proxyTargetClass = false 使用JDK * 有接口 proxyTargetClass = true 使用CGLIB * 没有接口 proxyTargetClass = false 使用CGLIB(这种情况下proxyTargetClass会在上面第269行代码处里面被修正为true) * 没有接口 proxyTargetClass = true 使用CGLIB */ @Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { /* 是否设置的代理应该执行激进的优化; 或者@EnableAspectJAutoProxy注解中的proxyTargetClass属性为true(为true代表CGLIB代理); 又或者配置类的代理接口是否实现了SpringProxy接口(或者根本没有实现任何代理接口) */ 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."); } //如果被代理的类是接口,又或者被代理的类是动态生成的,就创建JDK动态代理 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } //否则就创建CGLIB代理 return new ObjenesisCglibAopProxy(config); } else { //上面三个条件都不满足的话,就创建JDK动态代理 return new JdkDynamicAopProxy(config); } } /** * JdkDynamicAopProxy: * 第297行代码处: * 这里以JDK动态代理为例 */ @Override public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource()); } //获取所有JDK动态代理的接口 Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); //如果接口上有equals或者hashCode方法,就将这两个标志位置为true findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); //通过Proxy.newProxyInstance的方式来创建JDK动态代理 return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }方法调用以默认的JDK动态代理为例,在调用目标方法时会首先调用到JdkDynamicAopProxy的invoke方法:
/** * JdkDynamicAopProxy: */ @Override @Nullable public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object oldProxy = null; boolean setProxyContext = false; //获取代理的目标类 TargetSource targetSource = this.advised.targetSource; Object target = null; try { if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) { //判断代理的方法是否是equals方法,如果是的话就不进行代理 return equals(args[0]); } else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { //判断代理的方法是否是hashCode方法,如果是的话就不进行代理 return hashCode(); } else if (method.getDeclaringClass() == DecoratingProxy.class) { //如果调用的是DecoratingProxy类中的getDecoratedClass方法,就不会使用增强,直接返回目标类 return AopProxyUtils.ultimateTargetClass(this.advised); } else if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) { //如果代理的是Advised的子接口,就直接反射调用目标方法,也不会进行增强 return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args); } Object retVal; /* 这里就是在找@EnableAspectJAutoProxy注解中的exposeProxy配置值,如果为true,就是需要暴露代理对象的 JDK动态代理中一个方法调用同一个类中的其它方法时是不会被增强的,所以需要暴露代理对象,以解决这个问题 */ if (this.advised.exposeProxy) { //设置代理对象缓存(ThreadLocal) oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } //获取目标类实例 target = targetSource.getTarget(); //获取目标类Class对象 Class<?> targetClass = (target != null ? target.getClass() : null); //获取方法上的拦截器链(把之前获取到的Advisor转换成拦截器) List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); if (chain.isEmpty()) { //如果没有拦截器链,就直接反射调用目标方法(连接点)就行了 Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse); } else { //创建反射方法调用对象 MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); //通过责任链调用目标方法 retVal = invocation.proceed(); } //获取目标方法返回值类型 Class<?> returnType = method.getReturnType(); if (retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) { //如果返回值是目标类,就返回代理类 retVal = proxy; } else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) { //如果返回值是null,但是返回类型不是Void,说明执行目标方法抛出异常了,所以也在这里抛出异常 throw new AopInvocationException( "Null return value from advice does not match primitive return type for: " + method); } return retVal; } finally { if (target != null && !targetSource.isStatic()) { targetSource.releaseTarget(target); } if (setProxyContext) { AopContext.setCurrentProxy(oldProxy); } } } /** * ReflectiveMethodInvocation: * 第59行代码处: * 调用各个通知和目标方法 */ @Override @Nullable public Object proceed() throws Throwable { //当拦截器(通知)的索引计数已经到了最后一个,这个时候就需要调用目标方法(连接点)了 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } //获取下一个通知(通过拦截器索引计数+1的方式来获取) Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { //如果是InterceptorAndDynamicMethodMatcher类型的通知,则进行特殊处理 InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass()); if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) { return dm.interceptor.invoke(this); } else { //动态匹配失败的话,就跳过当前通知,继续调用下一个 return proceed(); } } else { //这里会使用责任链模式和递归的方式来逐个调用所有的通知 return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } } /** * 第95行代码处: */ @Nullable protected Object invokeJoinpoint() throws Throwable { //反射调用目标方法(连接点) return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments); }各个通知之间是通过责任链和递归的方式来进行调用的,具体的执行逻辑如下图所示:
较真儿学源码系列-Spring全家桶 目录概览
Spring Framework:
Spring IoC核心流程源码分析➡Spring AOP核心流程源码分析⬅Spring事务管理核心流程源码分析Spring MVC核心流程源码分析Spring Boot:
Spring Boot自动装配核心流程源码分析Spring Cloud
Spring Cloud OpenFeign核心流程源码分析Spring Cloud Netflix:
Spring Cloud Netflix Eureka核心流程源码分析Spring Cloud Netflix Ribbon核心流程源码分析Spring Cloud Netflix Hystrix核心流程源码分析Spring Cloud Alibaba:
Spring Cloud Alibaba Nacos核心流程源码分析Spring Cloud Alibaba Sentinel核心流程源码分析Spring Cloud Alibaba Seata核心流程源码分析原创不易,未得准许,请勿转载,翻版必究
