Spring(十七)Spring AOP 原理探究-aop解析入口分析

上一篇文章主要介绍了Spring AOP一些简单用法,当然如果要了解更多,可以选择再去看看Spring 文档。
博主还是喜欢从源码中知其所以然嘿嘿。

spring-boot-starter-aop

博主以 Spring-boot-starter-aop 为例,开始分析。
spring boot 中使用 aop,我们只需要引入 spring-boot-starter-aop 即可定义注解进行操作:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
            <version>2.1.7.RELEASE</version>
        </dependency>

spring-boot-starter-aop 反编译后的依赖来看,这个项目里面并没有任何代码:
在这里插入图片描述
没有任何代码,那么里面是怎么引入的呢?抱着这个想法,博主下载了Spring Boot项目源码查看,不过里面确实没有java代码,只有一个gradle依赖。

dependencies {
	api(platform(project(":spring-boot-project:spring-boot-dependencies")))
	api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter"))
	api("org.springframework:spring-aop")
	api("org.aspectj:aspectjweaver")
}

spring-boot-starter-aop 项目中,引入了一些依赖,包括 spring-aopajpectjweaver,以及当前spring-boot项目的starter

经过前面文章也有个大概了解,spring-aop项目中应该只是一些类,而没有注入到Spring 容器中,那么 spring-aop 的引线在哪里呢?

首先要使用spring-boot-starter-aop,首先得是一个spring-boot架构项目,而 spring-boot项目引入依赖的一个途径是通过增加Spring SPI配置文件: spring.factories,有加载 @EnableAutoConfiguration 进行加载,但很明显,spring-boot-starter-aop 不属于这一类。

在针对 @SpringBootApplication 进行更细致分析,它在 spring-boot-autoconfigure 包下面:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
...
}

上面 SpringBootApplication 注解中,使用 @ComponentScan 对当前包下进行进一步扫描,此时可以看到有个aop 的子包,下面有个配置类 AopAutoConfiguration。没错,这就是 spring-boot 中,spring-aop的入口:

@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {

	@Configuration
	@EnableAspectJAutoProxy(proxyTargetClass = false)
	@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
			matchIfMissing = false)
	public static class JdkDynamicAutoProxyConfiguration {

	}

	@Configuration
	@EnableAspectJAutoProxy(proxyTargetClass = true)
	@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
			matchIfMissing = true)
	public static class CglibAutoProxyConfiguration {

	}

}
  1. @Configuration 说明是配置类,会被spring扫描到
  2. @ConditionalOnClass 即当前classpath下面,有这几个类EnableAspectJAutoProxyAspectAdviceAnnotatedElement 才回去加载该类,通俗说就是 即有spring-aop 依赖才会加载。
  3. @ConditionalOnProperty 在上一步,再一步对配置进行条件判断,即判断是否有spring.aop.auto=true 则加载。matchIfMissing = true 或者没有该配置,则默认加载配置。
    类上注解分析完,下面看内部类注解:
  4. spring 代理方式有两种,一种是jdk代理(需要有接口方式进行代理),一种是cglib方式(不需要接口,以子类方式,但是无法代理final方法)。如上面配置,默认下是使用 cglib进行代理。

下面看两个子类都有的注解 @EnableAspectJAutoProxy

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
	boolean proxyTargetClass() default false;
	boolean exposeProxy() default false;

}

除了两个属性外,还引入了一个 AspectJAutoProxyRegistrarAspectJAutoProxyRegistrar 则为一个 ImportBeanDefinitionRegistrar,它将重写 registerBeanDefinitions 来注册自己的bean。

	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
			// 注册 AnnotationAwareAspectJAutoProxyCreator
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
		// 设置 EnableAspectJAutoProxy 来的两个属性 proxyTargetClass 和 exposeProxy 到 AnnotationAwareAspectJAutoProxyCreator 中
		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAspectJAutoProxy != null) {
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}
  1. 注册 AnnotationAwareAspectJAutoProxyCreator,这是spring-aop的核心入口类。
  2. 设置 EnableAspectJAutoProxy 来的两个属性 proxyTargetClassexposeProxyAnnotationAwareAspectJAutoProxyCreator 中。

AnnotationAwareAspectJAutoProxyCreator

在这里插入图片描述
排除众多类结构,发现 AnnotationAwareAspectJAutoProxyCreator 是一个 SmartInstantiationAwareBeanPostProcessor,和解析@Autowired 的类实现同一个接口,大概能猜到,在spring 容器初始化bean时候,对对应类进行代理操作 。
实现 SmartInstantiationAwareBeanPostProcessor 接口,需要实现以下方法(当然全部有默认接口):

  1. Class<?> predictBeanType(Class<?> beanClass, String beanName):预测bean类型
  2. Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) 解析获取候选构造方法
  3. Object getEarlyBeanReference(Object bean, String beanName) 获取bean实例,主要目的是解决spring循环依赖
  4. Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 实例前处理
  5. boolean postProcessAfterInstantiation(Object bean, String beanName) 实例后处理
  6. PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) 设置一些属性
  7. PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) 设置一些属性值
  8. Object postProcessBeforeInitialization(Object bean, String beanName) 实例化前处理
  9. Object postProcessAfterInitialization(Object bean, String beanName) 实例化后处理

AnnotationAwareAspectJAutoProxyCreator 主要对以下几个方法有具体实现:

  1. predictBeanTypeAbstractAutoProxyCreator 有实现
  2. getEarlyBeanReferenceAbstractAutoProxyCreator 有实现
  3. postProcessBeforeInstantiationAbstractAutoProxyCreator 有实现
  4. postProcessAfterInitializationAbstractAutoProxyCreator 有实现

下面从spring容器执行方法先后顺序,结合例子具体分析spring-aop 原理。

postProcessBeforeInstantiation

在实例化前进行调用:

	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
	// 获取即将缓存名字,有beanName,则返回beanName,如果为FactoryBean类型,则加上FactoryBean&前缀;没有beanName,则直接返回beanClass
		Object cacheKey = getCacheKey(beanClass, beanName);
		// 如果没有beanName,或者不在 targetSourcedBeans中
		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
			if (this.advisedBeans.containsKey(cacheKey)) {
			// 如果已包含该key,则说明已经处理过了
				return null;
			}
			// 如果该bean是spring-aop的框架内部bean,即 Advice,Pointcut,Advisor,AopInfrastructureBean 几种bean。或者有@Aspect注解,或者,这个bean类,本身就是aspectj创建。 则加入到advisedBeans bean 并跳过。
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}

		// Create proxy here if we have a custom TargetSource.
		// Suppresses unnecessary default instantiation of the target bean:
		// The TargetSource will handle target instances in a custom fashion.
		TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
		if (targetSource != null) {
			if (StringUtils.hasLength(beanName)) {
				this.targetSourcedBeans.add(beanName);
			}
			Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
			Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		return null;
	}
  1. 获取即将缓存名字,有beanName,则返回beanName,如果为FactoryBean类型,则加上FactoryBean&前缀;没有beanName,则直接返回beanClass。
  2. 对bean进行处理,判断是否需要跳过。isInfrastructureClass 逻辑主要是要跳过以下几种类型:
  • Advice,Pointcut,Advisor,AopInfrastructureBean 几种bean类型。或者有@Aspect注解,或者,这个bean类,本身就是aspectj创建。
    shouldSkip 主要有以下几种判断:
  • 获取advisor过程,这个看下一小节
  • 如果有一种类型为 AspectJPointcutAdvisor 则直接跳过
  • 执行父类的 shouldSkip 方法,父类主要是 判断 跳过 original instance 类型bean
  1. 如果有配置 targetSource,则调用 getAdvicesAndAdvisorsForBean 获取代理接口,并调用创建代理类接口。
findCandidateAdvisors

findCandidateAdvisors 是获取Advisor 过程:
AnnotationAwareAspectJAutoProxyCreatorfindCandidateAdvisors方法:

	@Override
	protected 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;
	}

看父类的 AbstractAdvisorAutoProxyCreator 中方法:

	protected List<Advisor> findCandidateAdvisors() {
		Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
		return this.advisorRetrievalHelper.findAdvisorBeans();
	}

具体使用 BeanFactoryAdvisorRetrievalHelperfindAdvisorBeans,这个方法主要目的是找到所有 资格的 Advisor bean类,该方法会忽略 FactoryBean 类型,以及排除 正在创建的bean。

	public List<Advisor> findAdvisorBeans() {
		// Determine list of advisor bean names, if not cached already.
		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!
			// 直接从beanFactory中获取所有Advisor类。
			advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
					this.beanFactory, Advisor.class, true, false);
			this.cachedAdvisorBeanNames = advisorNames;
		}
		if (advisorNames.length == 0) {
			return new ArrayList<>();
		}

		List<Advisor> advisors = new ArrayList<>();
		for (String name : advisorNames) {
			if (isEligibleBean(name)) {
				if (this.beanFactory.isCurrentlyInCreation(name)) {
					if (logger.isTraceEnabled()) {
						logger.trace("Skipping currently created advisor '" + name + "'");
					}
				}
				else {
					try {
						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;
					}
				}
			}
		}
		return advisors;
	}

在Spring中,也可以直接使用@Aspect注解,当从 findAdvisorBeans 没有获取到信息是,会尝试调用 BeanFactoryAspectJAdvisorsBuilderbuildAspectJAdvisors() 获取注解。

	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<>();
					// 获取所有实例,即Object子类。
					String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
							this.beanFactory, Object.class, true, false);
					for (String beanName : beanNames) {
						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.
						Class<?> beanType = this.beanFactory.getType(beanName);
						if (beanType == null) {
							continue;
						}
						if (this.advisorFactory.isAspect(beanType)) {
						// 如果是 @Aspect注解且不是aspectj动态产生的。那额
							aspectNames.add(beanName);
							// 构造 Aspect 元数据
							AspectMetadata amd = new AspectMetadata(beanType, beanName);
							if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
							// 如果改AspectJ 注解 是单例模型
							// 构造一个 BeanFactoryAspectInstanceFactory
								MetadataAwareAspectInstanceFactory factory =
										new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
								// 获取在Advice 中配置的Advisor,即PointCut信息。
								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);
										// 构造MetadataAwareAspectInstanceFactory  并缓存
								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<>();
		// 从获取到的有Aspecj 注解的类,进行获取其 Advisor过程
		for (String aspectName : aspectNames) {
			List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
			if (cachedAdvisors != null) {
				advisors.addAll(cachedAdvisors);
			}
			else {
				MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
				// 构造 MetadataAwareAspectInstanceFactory  并加入
				advisors.addAll(this.advisorFactory.getAdvisors(factory));
			}
		}
		return advisors;
	}

整个 findCandidateAdvisors 方法有点长,但是代码逻辑还是挺容易理解的

  1. 调用父类方法 findCandidateAdvisors 获取 Advisor 类型类,即实现了 Advisor 接口类。AdvisorAdvice的一个点,实际上为 Advice 的一个切点(JoinPoint)。这个接口一般不建议给Spring 使用者用,而提供给Spring 所需要的的维护者使用。
  2. 再从 BeanFactoryAspectJAdvisorsBuilderbuildAspectJAdvisors 中,将所有切面 @Advice 从beanFactory解析出,并且分别解析其PointCut,每个拦截方法,使用 Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class 注解,就是一个 Advisor
this.advisorFactory.getAdvisors(factory)

往下看 this.advisorFactory.getAdvisors(factory) 具体内容:

	public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
	// 获取目标代理类
		Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
		// 获取切面名字
		String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
		validate(aspectClass);

		// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
		// so that it will only instantiate once.
		// 判断是否为懒加载切面
		MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
				new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

		List<Advisor> advisors = new ArrayList<>();
		for (Method method : getAdvisorMethods(aspectClass)) {
		// 获取该切面类的切点信息
			Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
			if (advisor != null) {
				advisors.add(advisor);
			}
		}

		// If it's a per target aspect, emit the dummy instantiating aspect.
		if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
			Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
			advisors.add(0, instantiationAdvisor);
		}

		// Find introduction fields.
		// 对 @DeclareParent 注解进行处理
		for (Field field : aspectClass.getDeclaredFields()) {
			Advisor advisor = getDeclareParentsAdvisor(field);
			if (advisor != null) {
				advisors.add(advisor);
			}
		}

		return advisors;
	}

上面代码中,看对普通增强器获取,主要方法为: getAdvisor:

	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;
		}
		// 包装一层 InstantiationModelAwarePointcutAdvisorImpl
		return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
				this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
	}

其实对于普通使用 @Aspectj 切面的处理,就是将其切点信息PointCut 获取出来并处理:

	@Nullable
	private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
	// 获取Pointcut, Around, Before, After, AfterReturning, AfterThrowing
		AspectJAnnotation<?> aspectJAnnotation =
				AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
		if (aspectJAnnotation == null) {
			return null;
		}
		// 设置poincut信息后取出。
		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;
	}

上面代码片段中,对每个方法进行获取增强器操作,而后封装为 InstantiationModelAwarePointcutAdvisorImpl 返回。
InstantiationModelAwarePointcutAdvisorImpl 的构造方法,则是普通信息的填充,而主要是其内部的 instantiateAdvice ,对信息进行初始化过程。

	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);
	}

再看 ReflectiveAspectJAdvisorFacotorygetAdvice 方法:

	@Override
	@Nullable
	public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
			MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
		// 切面类
		Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
		validate(candidateAspectClass);
		// 获取方法上面注解
		AspectJAnnotation<?> aspectJAnnotation =
				AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
		if (aspectJAnnotation == null) {
			return null;
		}

		// If we get here, we know we have an AspectJ method.
		// Check that it's an AspectJ-annotated class
		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:
				if (logger.isDebugEnabled()) {
					logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
				}
				return null;
			case AtAround:
			// candidateAdviceMethod 为候选方法,expressionPointcut 为注解上面切点信息, aspectInstanceFactory 为
				springAdvice = new AspectJAroundAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				break;
			case AtBefore:
				springAdvice = new AspectJMethodBeforeAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				break;
			case AtAfter:
				springAdvice = new AspectJAfterAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				break;
			case AtAfterReturning:
				springAdvice = new AspectJAfterReturningAdvice(
						candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
				AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
				if (StringUtils.hasText(afterReturningAnnotation.returning())) {
					springAdvice.setReturningName(afterReturningAnnotation.returning());
				}
				break;
			case AtAfterThrowing:
				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);
		}

		// Now to configure the advice...
		springAdvice.setAspectName(aspectName);
		springAdvice.setDeclarationOrder(declarationOrder);
		String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
		if (argNames != null) {
			springAdvice.setArgumentNamesFromStringArray(argNames);
		}
		springAdvice.calculateArgumentBindings();

		return springAdvice;
	}

根据不同类型AspectJ注解,Spring 封装了不同类返回。
主要有以下几种:

  • @Around: AspectJAroundAdvice
  • @Before: AspectJMethodBeforeAdvice
  • @After: AspectJAfterAdvice
  • @AfterReturning: AspectJAfterReturningAdvice
  • @AfterThrowing: AspectJAfterThrowingAdvice

小结

本文主要分析Spring AOP入口,以及postProcessBeforeInstantiation 部分内容,下文将针对 具体 createProxy 具体分析

觉得博主写的有用,不妨关注博主公众号: 六点A君。
哈哈哈,一起研究Spring:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值