刚开始看源码,很多地方理解不深,本文适合作为入门教程。欢迎各位大佬指教 : )
零、术语及概念
1.1 Advisor
-
==Advisor== 是 ==PointCut==、==Advice== 的结合,是 Spring Aop 的顶层抽象。
-
其继承体系主要有两个
PointCutAdvisor、IntroductionAdvisor -
IntroductionAdvisor:只能应用于类级别的拦截。
一、AOP功能的引入—— AnnotationAwareAspectJAutoProxyCreator
aop功能由@EnableAspectJAutoProxy引入
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 会注册 AnnotationAwareAspectJAutoProxyCreator,见下面代码
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
// 注册 AnnotationAwareAspectJAutoProxyCreator
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
aop 的功能主要是由 ==AnnotationAwareAspectJAutoProxyCreator== 提供的,其继承关系图如下:
可以看出 AnnotationAwareAspectJAutoProxyCreator 的父类有 BeanPoseProcessor。BeanPostProcessor 接口方法有 postProcessorAfterInitialization,会在 bean 初始化之后调用。
public interface BeanPostProcessor {
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
二、构建适用于 bean 上的 advisor
整体流程图如下:
由第一节知,入口为 AnnotationAwareAspectJAutoProxyCreator#postProcessorAfterInitailization
AbstractAutoProxyCreator:
=== postProcessAfterInitialization:
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 此方法主要判断 bean 是否需要被代理
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
=== wrapIfNecessary:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 当前 bean 是否在 targetSourcedBeans 缓存中存在(已经被处理过),如果存在直接返回
// targetSourcedBeans.add 在 beforePostProcessInitialization() 中
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// bean 是 aop 基础类 或者 应该跳过
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 关注,见 code1
// 作用:获取该 bean 的 advisor 或 advice
// 具体逻辑在 AbstractAdvisorAutoProxyCreator 中
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 需要对 bean 进行代理
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;
}
code1 —— Advisor 获取流程 —— AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
// 查找该 bean 上有效的 Advisor
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 此方法在 AnnotationAwareAspectJAutoProxyCreator 中有子类实现
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 在 advisor 中查找适用于当前 bean 的advisor
// 见代码段 code2
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 在拦截器链最前面加 ExposeInvocationInterceptor.ADVISOR 即 DefaultPointcutAdvisor
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
// AnnotationAwareAspectJAutoProxyCreator 子类具体实现
protected List<Advisor> findCandidateAdvisors() {
// 获取 advisors,关注
List<Advisor> advisors = super.findCandidateAdvisors();
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
1. findCandidateAdvisors
接下来看 findCandidateAdvisors(),==其具体实现在 BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans 中==
protected List<Advisor> findCandidateAdvisors() {
// 获取 advisors
List<Advisor> advisors = super.findCandidateAdvisors();
// 为 bean 工厂构建 advisor
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
2. buildAspectJAdvisors
BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors:
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
/*
* this.aspectBeanNames 缓存为空,即未处理过,才执行以下逻辑
* 在 postProcessBeforeInstantiation 进入到此方法中时,缓存为 null
* 在 postProcessAfterInstantiation 之后的流程中,缓存不为空
*/
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
/*
* 参数 Object.class,表示取出所有的 bean。
* 此方法非常耗时,所以 spring 在此处设置了缓存机制
* 即 this.aspectBeanNames
*/
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
// 紧接着遍历 beanName
for (String beanName : beanNames) {
// 跳过不合法的 beanName
if (!isEligibleBean(beanName)) { continue; }
// 通过 beanName 获取 class 信息
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) { continue; }
// 处理标有 AspectJ 注解的类
if (this.advisorFactory.isAspect(beanType)) {
// 加入缓存
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
/*
* 实际类型是 BeanFactoryAspectInstanceFactory
* 会根据 beanName 查找对应 class 属性
* 把 beanName,class 封装到 AspectMetadata 中
*/
MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
/**
* 解析拦截方法,生成增强器
*
* 利用 factory 中的 beanName, 获取其 class 信息,然后
* 1.解析 @pointCut 上的表达式,封装成 AspectJExpressionPointcut
* 2.获取 @Before、@After 等方法,封装成 Method
* 3.把上述参数封装成 InstantiationModelAwarePointcutAdvisorImpl,即 Advisor 的子类
*
* 具体实现在 ReflectiveAspectJAdvisorFactory#getAdvisors 中
* 为了不影响对整体流程的分析,此方法的具体实现放在文章末尾
*/
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
// 单例直接将解析的增强方法放入缓存
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
// 不是单例则缓存 factory
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("");
}
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;
}
2. findAdvisorsThatCanApply
AopUtils#findAdvisorsThatCanApply:
/**
* @param candidateAdvisors 上一步 findCandidateAdvisor 中返回的,即所有的 Advisor
* @param clazz beanClass
*/
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
for (Advisor candidate : candidateAdvisors) {
// 引介增强
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
// 普通增强 PointcutAdvisor
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
AopUtils#canApply:
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
return true;
}
// AspectJExpressionPointcut,切点表达式的 matcher
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet<>();
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
// 如果切点表达式 matcher 不为 null,则用切点表达式匹配
if (introductionAwareMethodMatcher != null ? introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) : methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
三、生成代理对象
继续回到 ==AbstractAutoProxyCreator#wrapIfNecessary==,在此方法中,主要有 2 个重要过程:
- 获取 bean 上的 advisor
- 以获取到的 advisor 为参数,生成代理对象
AbstractAutoProxyCreator#wrapIfNecessary:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 当前 bean 是否在 targetSourcedBeans 缓存中存在(已经被处理过),如果存在直接返回
// targetSourcedBeans.add 在 beforePostProcessInitialization() 中
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// bean 是 aop 基础类 或者 应该跳过
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 创建代理,对于代理的创建委托给了 proxyFactory 处理,此方法主要做 proxyFactory 的初始化工作。主要有以下几点:
- 属性拷贝
- setProxyTargetClass() 来确定代理的方式
- 添加代理接口
- 包装 advisor
- 执行定制函数 customizeProxyFactory()
- 创建代理
protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// proxyTargetClass 默认为 false,true 使用 CGLib 代理,false 使用 jdk 动态代理
if (!proxyFactory.isProxyTargetClass()) {
// 判断是否基于类代理,即 CGLib 代理
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}else {
// 对代理接口做进一步评估,见 code
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 把拦截器包装为 advisor,具体见 code
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
//
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 调用 getProxy()
return proxyFactory.getProxy(getProxyClassLoader());
}
code2 —— 构造 advisor —— AbstractAutoProxy#buildAdvisors
此方法中,把所有的拦截器统一封装成 advisor
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
// 解析公共拦截器
Advisor[] commonInterceptors = resolveInterceptorNames();
List<Object> allInterceptors = new ArrayList<>();
if (specificInterceptors != null) {
allInterceptors.addAll(Arrays.asList(specificInterceptors));
// 判断一下优先级
if (commonInterceptors.length > 0) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
}
else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
// 将拦截器包装成 advisor
// DefaultAdvisorAdapterRegistry.wrap()
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
继续看包装流程,this.advisorAdapterRegistry 实际对象为 ==DefaultAdvisorAdapterRegistry==。
DefaultAdvisorAdapterRegistry#wrap:
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
/*
* 后置通知:AspectJAfterAdvice,前置通知:MethodBeforeAdviceInterceptor
* 等都是 MethodInterceptor 的子类
*/
if (advice instanceof MethodInterceptor) {
return new DefaultPointcutAdvisor(advice);
}
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
code3 —— 创建代理 —— ProxyFactory
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
先来看 createAopProxy(),其具体实现在 DefaultAopProxyFactory#createAopProxy中:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
/*
* CGLib 代理
* optimize:用于控制通过cglib创建的代理是否使用激进的优化策略。除非完全了解AOP如何处理代理优化,
* isProxyTargetClass:默认为 false,可以手动配置,为 true 时,强制使用 CGLib 代理
* config:ProxyFactory
* hasNoUserSuppliedProxyInterfaces: 判断是否实现了接口
*/
if (!IN_NATIVE_IMAGE && (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("xxx");
}
/*
* 要被代理的对象是接口 || targetClass是Proxy class
* 使用 JDK 动态代理
*/
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
此方法会根据情况选择代理方式:
- bean 如果实现了接口,默认会选择 jdk 动态代理,但可以通过配置 proxyTargetClass=true 强制使用 CGLib 代理
- bean 没有实现接口,只能使用 CGLib 代理
四、invoke
1. JdkDynamicAopProxy
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)) {
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 获取拦截器链,由 advisorChainFactory 完成
// 见 code
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// chain 包装到 MethodInvocation 中
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 具体执行分析,见 code
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()) {
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);
}
}
}
code4 —— ReflectiveMethodInvocation
public Object proceed() throws Throwable {
// this.currentInterceptorIndex 初始为 -1
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 依此获取 chain 中拦截器,index=0 时为 ExposeInvocationInterceptor
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof 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 {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
/*
* 在获取 advisor 过程中,会根据不同的通知类型返回不同的实现类,具体可看第五段
* 这里会执行对应的实现类的 invoke 方法
*
* before: MethodBeforeAdviceInterceptor
* after: AspectJAfterAdvice
*
* @param this 上面的 new ReflectiveMethodInvocation().proceed()
*/
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
2. CGLib
==前置通知== MethodBeforeAdviceInterceptor:
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
==后置通知== AspectJAfterAdvice:
public Object invoke(MethodInvocation mi) throws Throwable {
try {
// 先执行方法本体
return mi.proceed();
}finally {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
五、Advisor 获取的具体过程
BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors
主要流程见 code1 中的 2,:
- 获取所有的 beanName
- 遍历 beanName,找出存在 @AspectJ 注解的 beanName
- 对于存在 @AspectJ 注解的 beanName,解析其中的增强方法,如 @After、@Before
- 将第 3 步中的结果加入到缓存中
1. ReflectiveAspectJAdvisorFactory#getAdvisors
ReflectiveAspectJAdvisorFactory#getAdvisors:
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
// 获取到 aspect 切面的 name 及 class
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
validate(aspectClass);
// 包装此 aspectInstanceFactory,使其只实例化一次
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
// getAdvisorMethods(), 反射获取切面中所有的通知方法,即非 @pointCut 注解标注的方法
for (Method method : getAdvisorMethods(aspectClass)) {
// 生成增强器,具体见下面代码
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
ReflectiveAspectJAdvisorFactory#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
);
}
继续看 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()) {
// 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;
//
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
// 这里具体实现在 ReflectiveAspectJAdvisorFactory#getAdvice
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}
/**
继续看 getAdvice 方法,在此方法中,会根据注解的类型返回不同的实现类
- AspectJMethodBeforeAdvice
- AspectJAroundAdvice
- AspectJAfterAdvice
- AspectJAfterReturningAdvice
ReflectiveAspectJAdvisorFactory#getAdvice:
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();
}
if (logger.isDebugEnabled()) {
logger.debug();
}
AbstractAspectJAdvice springAdvice;
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
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;
}