上一篇分享了,spring 中bean实例的循环依赖,今天开始分享解析AOP 源码。
1、首先从源码中AOP 的入口方法开始, AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory 类中的方法如下:
try {
// IOC 依赖注入的核心方法
populateBean(beanName, mbd, instanceWrapper);
//bean 实例化和Ioc依赖注入完以后的调用,这里就是AOP 的入口,点击进入
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//调用Aware方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//对类中某些特殊方法的调用,比如@PostConstruct,Aware接口
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//InitializingBean接口,afterPropertiesSet,init-method属性调用
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//这里可能生出代理实例,是aop的核心入口,点击进入-->
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
来到这个方法:
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {//获取所有的BeanPostProcessors,进行遍历
//这是一个 BeanPostProcessor 接口的埋点运用,进入后选择实现类-->
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
2、进入接口后ctrl+t 显示多个实现类:
很明显我们进入 AbstractAutoProxyCreator 类,进入的原因如下:
因为AbstractAutoProxyCreator最终是实现了InstantiationAwareBeanPostProcessor接口,因此,resolveBeforeInstantiation方法中的applyBeanPostProcessorsBeforeInstantiation方法中的代码ibp.postProcessBeforeInstantiation(beanClass, beanName)方法循环调用最终可以调用的是AbstractAutoProxyCreator类中的postProcessBeforeInstantiation方法完成的AOP相关横切逻辑的加载与解析的。SPI思想关注一下,里面实例化了一些重要的实例:
为什么会调用到这里,有个重要的注解需要添加,否则Debug不会走到这里,注解配置如下:
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
/**
* @Author nandao
* Date 2022/7/12 14:09
* Version 1.0
*/
@Component
//@EnableAspectJAutoProxy(proxyTargetClass = false,exposeProxy = true)
@EnableAspectJAutoProxy //核心注解
public class AopConfig {
}
参考AOP实现原理:核心介绍该注解的原理。
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);//核心方法在这,点击进入-->
}
}
return bean;
}
来到:
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;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
//该方法去寻找advisor 切面,如果这个bean有advice的话,就创建当前bean的代理,点击进入-->
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//如果有切面,则生成该bean的代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//把被代理对象bean实例封装到SingletonTargetSource对象中
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;
}
业务伪代码测试
package com.enjoy.jack.aop.aspectj;
import com.enjoy.jack.annotation.EasyCache;
import org.aopalliance.intercept.MethodInvocation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.List;
@Component
@Aspect
public class AspectAnnotation {
@Pointcut(value = "execution(public * com.enjoy.jack.service.*.*(..)) && args(a)",argNames = "a")
public void pc2(List a){}
@Pointcut(value = "execution(public * com.enjoy.jack.service.*.*(..))")
public void pc1(){}
@Before("pc1()")
public void Abefore13() {
MethodInvocation methodInvocation = ExposeInvocationInterceptor.currentInvocation();
Method method = methodInvocation.getMethod();
boolean annotationPresent = method.isAnnotationPresent(EasyCache.class);
System.out.println("==============AspectAnnotation Abefore13=========" + annotationPresent);
}
@Before("pc1()")
public void before13() {
MethodInvocation methodInvocation = ExposeInvocationInterceptor.currentInvocation();
System.out.println("==============AspectAnnotation before13=========");
}
@Before("pc1()")
public void before132() {
System.out.println("==============AspectAnnotation before132=========");
}
@Before("pc1()")
public void before1() {
System.out.println("==============AspectAnnotation before1=========");
}
@Before(value = "pc1()",argNames = "joinPoint")
public void before2(JoinPoint joinPoint) {
System.out.println("==============AspectAnnotation before2=========");
}
@After(value = "pc1()")
public void AAfter() {
System.out.println("==============AspectAnnotation AAfter=========");
}
@Around(value = "pc2(a)",argNames = "a")
public Object around(ProceedingJoinPoint joinPoint, List a) throws Throwable {
System.out.println("==============AspectAnnotation around前置通知=========");
Object result = joinPoint.proceed();
System.out.println("==============AspectAnnotation around后置通知=========");
return result;
}
@Around(value = "pc1()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("==============AspectAnnotation around前置通知=========");
Object result = joinPoint.proceed();
System.out.println("==============AspectAnnotation around后置通知=========");
return result;
}
@AfterReturning(value = "pc1()",returning = "retVal")
public void afterReturning(JoinPoint joinPoint, Object retVal) {
System.out.println("==============AspectAnnotation 后置通知 拿返回值=========" + retVal);
}
@AfterThrowing(value = "pc1()",throwing = "e")
public void afterThrowing(JoinPoint joinPoint, Throwable e) {
System.out.println("AspectAnnotation 异常通知 拿异常=========" + e);
}
}
断点走到
继续:
3、进入 AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator 的 getAdvicesAndAdvisorsForBean 方法:
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
//寻找到合格的切面,收集起来,点击进入-->
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
来到-->
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//找到候选的切面,其实就是一个寻找有@Aspectj 和相关 注解的过程,把工程中所有有这个注解的类封装成Advisor返回,点击进入-->
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//判断上面收集的切面是否作用在当前 beanClass 上面(即是否在:pointcut 的表达式目录里),就是一个匹配过程。把作用在当前beanClass 上面的 Advisor 的集合返回到上游,等待创建代理类
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
//针对@Aspect注解切面添加了一个默认的切面 DefaultPointcutAdvisor
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
//对有@Order@Priority进行排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
4、ctrl+t 显示:很明显 进入 AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator 类的
进入
@Override
protected List<Advisor> findCandidateAdvisors() {
//找到所有的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.
//这里开始创建候选的切面, 对@Aspect注解的类进行处理,点击进入-->
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
5、来到 BeanFactoryAspectJAdvisorsBuilder
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<>();
//获取spring容器中的所有bean的名称BeanName,并遍历循环
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;
}
//判断类上是否有@Aspect注解,如果有,该类就很可能有切面
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
//创建获取有@Aspect注解类的实例工厂,负责获取有@Aspect注解类的实例
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//创建并获取切面advisor对象,点击进入-->
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 {
// Per target or per this.
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);
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;
}
生成后有个映射关系保存
6、ctrl+T 进入 ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable 类的 getAdvisors 方法:
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
//从工厂中获取有@Aspect注解的类Class
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
//从工厂中获取有@Aspect注解的类的名称
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<>();
//这里循环没有@Pointcut注解的方法
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.
for (Field field : aspectClass.getDeclaredFields()) {
//判断属性上是否有DeclareParents注解,如果有返回切面
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
点击getAdvisorMethods(aspectClass) 方法,获取后有个排序的过程,基于两个原则
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
final List<Method> methods = new ArrayList<>();
ReflectionUtils.doWithMethods(aspectClass, method -> {
// Exclude pointcuts
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
}, ReflectionUtils.USER_DECLARED_METHODS);
if (methods.size() > 1) {
//按照注解先后顺序+自然顺序排序
methods.sort(METHOD_COMPARATOR);
}
return methods;
}
点击 METHOD_COMPARATOR,进入 ReflectiveAspectJAdvisorFactory 看到初始化好的数据
private static final Comparator<Method> METHOD_COMPARATOR;
static {
// Note: although @After is ordered before @AfterReturning and @AfterThrowing,
// an @After advice method will actually be invoked after @AfterReturning and
// @AfterThrowing methods due to the fact that AspectJAfterAdvice.invoke(MethodInvocation)
// invokes proceed() in a `try` block and only invokes the @After advice method
// in a corresponding `finally` block.
//先按照注解的顺序排序
Comparator<Method> adviceKindComparator = new ConvertingComparator<>(
new InstanceComparator<>(
Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
(Converter<Method, Annotation>) method -> {
AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
return (ann != null ? ann.getAnnotation() : null);
});
Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName);
//按照自然的排序,比如before1、before12、cbefore等等,下面有示例证明
METHOD_COMPARATOR = adviceKindComparator.thenComparing(methodNameComparator);
}
测试参数演示证明
然后返回来到 getAdvisor 方法:
@Override
@Nullable
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
//获取pointCut对象,最重要的是从注解中获取表达式,即需要代理增强的类所在的目录,点击进入-->
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
//创建Advisor切面类,这才是真正的切面类,一个切面类里面肯定要有1、pointCut 2、advice
//这里pointCut是expressionPointcut, advice 增强方法是 candidateAdviceMethod,点击-->
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
测试断点接口,对应业务接口
来到getPointcut 方法:
@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
//从候选的增强方法里面 candidateAdviceMethod 找有有注解
//Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
//并把注解信息封装成AspectJAnnotation对象,点击进入-->
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
//创建一个PointCut类,并且把前面从注解里面解析的表达式设置进去
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;
}
测试如图:
7、进入 AbstractAspectJAdvisorFactory implements AspectJAdvisorFactory 类中的
findAspectJAnnotationOnMethod 方法:
@SuppressWarnings("unchecked")
@Nullable
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
//遍历Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
//找到method方法里对应的注解(比如:@Around),然后把注解里面的信息封装成AspectJAnnotation对象返回,当然只会是一个对象
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
if (foundAnnotation != null) {
return foundAnnotation;
}
}
return null;
}
点击 ASPECTJ_ANNOTATION_CLASSES 查看
private static final Class<?>[] ASPECTJ_ANNOTATION_CLASSES = new Class<?>[] {
Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class};
来到:findAnnotation方法
@Nullable
private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
//找的规则就是找注解的父注解,递归的方式去找,直到找到目标注解为止
A result = AnnotationUtils.findAnnotation(method, toLookFor);
if (result != null) {
//把注解里面的信息解析出来,然后包装成AspectJAnnotation对象
return new AspectJAnnotation<>(result);
}
else {
return null;
}
}
点击 AnnotationUtils.findAnnotation(method, toLookFor);
@Nullable
public static <A extends Annotation> A findAnnotation(Method method, @Nullable Class<A> annotationType) {
if (annotationType == null) {
return null;
}
// Shortcut: directly present on the element, with no merging needed?
if (AnnotationFilter.PLAIN.matches(annotationType) ||
AnnotationsScanner.hasPlainJavaAnnotationsOnly(method)) {
return method.getDeclaredAnnotation(annotationType);
}
// Exhaustive retrieval of merged annotations...
return MergedAnnotations.from(method, SearchStrategy.TYPE_HIERARCHY, RepeatableContainers.none())
.get(annotationType).withNonMergedAttributes()
.synthesize(MergedAnnotation::isPresent).orElse(null);
}
测试首次遍历,发现注解不一致,返回空
遍历第二个注解:两者一致,会返回AspectJAnnotation<?>对象
请看,这里就返回一个代理对象:
返回生成 new AspectJAnnotation<>(result) 对象
public AspectJAnnotation(A annotation) {
this.annotation = annotation;
this.annotationType = determineAnnotationType(annotation);
try {
//解析注解上面的表达式,如@Around("pc1()"),获取到pc1()值
//@AfterReturning(pointcut = "execution(public * com.xiangxue.jack.service.*.*(..))")
this.pointcutExpression = resolveExpression(annotation);
//获取注解上的参数,比如@Around(value = "pc2(a)",argNames = "a") 上的 argNames = "a"
Object argNames = AnnotationUtils.getValue(annotation, "argNames");
this.argumentNames = (argNames instanceof String ? (String) argNames : "");
}
catch (Exception ex) {
throw new IllegalArgumentException(annotation + " is not a valid AspectJ annotation", ex);
}
}
测试进入,点击 determineAnnotationType(annotation);
查看 annotationTypeMap 集合,初始化的数据
点击 resolveExpression(annotation);接口返回值
8、回到上面结果如下:
继续走
返回 点击 InstantiationModelAwarePointcutAdvisorImpl 对象实现类的构造方法,InstantiationModelAwarePointcutAdvisorImpl implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation, Serializable
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;
//创建advice对象 点击进入--》
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}
测试参数
来到:
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
//创建Advice对象,如上:
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}
9、ctrl+t getAdvice 进入 ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable
@Override
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
//获取有@Aspect注解的类
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
//找到candidateAdviceMethod方法上面的注解,并且包装成AspectJAnnotation对象,这个对象中就有注解类型
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;
//根据不同的注解类型创建不同的advice类实例
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
//实现了MethodInterceptor接口
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
//实现了MethodBeforeAdvice接口,没有实现MethodInterceptor接口
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
//实现了MethodInterceptor接口
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
//实现了AfterReturningAdvice接口,没有实现MethodInterceptor接口
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
//实现了MethodInterceptor接口
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);
}
//计算argNames和类型的对应关系
springAdvice.calculateArgumentBindings();
return springAdvice;
}
测试参数
继续
然后返回
10、返回的 Advice 集合,返回途中经过几次过滤,重要的一次如下:
点击 findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
//看看当前类是否在这些切面的pointCut中.掉类和方法的match过程
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
点击 AopUtils.findAdvisorsThatCanApply 接口
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();
//调用pointCut中的ClassFilter 和methodMatcher的match方法的过程
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
if (canApply(candidate, clazz, hasIntroductions)) {//点击进入
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
点击 canApply(candidate, clazz, hasIntroductions)ff
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);//点击进入
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
点击canApply(pca.getPointcut(), targetClass, hasIntroductions)方法
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
//调用ClassFilter的matches方法,判断类是否匹配
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
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) {
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
测试参数演示不配当前实例:
换一个不匹配的实例
主要判断当前的bean是否在这个目录下,还有一种情况后期会分享就是,判断该方法是否有对应的自定义注解。
匹配的实例:
工程中共有10个切面对象,其中有9个可以匹配到当前对象。
返回之前添加一个默认切面 extendAdvisors(eligibleAdvisors); 进入AspectJAwareAdvisorAutoProxyCreator
@Override
protected void extendAdvisors(List<Advisor> candidateAdvisors) {
AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
}
点击
public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) {
// Don't add advisors to an empty list; may indicate that proxying is just not required
if (!advisors.isEmpty()) {
boolean foundAspectJAdvice = false;
for (Advisor advisor : advisors) {
// Be careful not to get the Advice without a guard, as this might eagerly
// instantiate a non-singleton AspectJ aspect...
if (isAspectJAdvice(advisor)) {
foundAspectJAdvice = true;
break;
}
}
if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {
advisors.add(0, ExposeInvocationInterceptor.ADVISOR);//添加默认的切面
return true;
}
}
return false;
}
点击看看,此切面作用是处理传参的,只要有@Aspect注解的类,就会多一个这样的切面, 因为切面调用时是链路调用。
public static final Advisor ADVISOR = new DefaultPointcutAdvisor(INSTANCE) {
@Override
public String toString() {
return ExposeInvocationInterceptor.class.getName() +".ADVISOR";
}
};
过滤后返回通用接口 Advice,直到这里转换成数组,承接下面的接口
11、到这里AOP 的切面已经生成,可以去创建代理了,入口如下:
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//如果有切面,则生成该bean的代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//把被代理对象bean实例封装到SingletonTargetSource对象中,代理类的调用入口--》下篇介绍
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
到此收获切面注解封装成对象advisors,准备结合当前的实例生成代理类,代理类的调用流程下一篇解析,敬请期待!