Spring-Aop 底层源码解析--Spring中Aspect切面逻辑的实现
前言
在Spring项目中我们可以在启动类上开启切面,并为已经存在的bean 增加@Aspect 声明为切面类,这样就可以为特定bean 中的方法增加对应的逻辑,那么Spring对于@Aspect 是如何支持的呢?
一、 aop 的相关概念:
- Aspect:表示切面,比如被@Aspect注解的类就是切面,可以在切面中去定义Pointcut、Advice等等
- Join point:表示连接点,表示一个程序在执行过程中的一个点,比如一个方法的执行,比如一个异常的处理,在Spring AOP中,一个- 连接点通常表示一个方法的执行。
- Advice:表示通知,表示在一个特定连接点上所采取的动作。Advice分为不同的类型,后面详细讨论,在很多AOP框架中,包括Spring,会用Interceptor拦截器来实现Advice,并且在连接点周围维护一个Interceptor链
- Pointcut:表示切点,用来匹配一个或多个连接点,Advice与切点表达式是关联在一起的,Advice将会执行在和切点表达式所匹配的连接点上
- Introduction:可以使用@DeclareParents来给所匹配的类添加一个接口,并指定一个默认实现
- Target object:目标对象,被代理对象
- AOP proxy:表示代理工厂,用来创建代理对象的,在Spring Framework中,要么是JDK动态代理,要么是CGLIB代理
- Weaving:表示织入,表示创建代理对象的动作,这个动作可以发生在编译时期(比如Aspejctj),或者运行时,比如Spring AOP
二、Spring Aspect 切面的实现:
2.1 准备工作:
启动类中增加切面扫描注解
@EnableAspectJAutoProxy
定义切面:
@Aspect
@Component
public class TestAspect {
@Before("execution(public void com.example.springdabaihua.aspect.service.AspectTestService.test())")
public void test(JoinPoint joinPoint){
System.out.println("test() before");
}
}
2.2 Spring 对切面的扫描:
2.2.1 初始的bean 定义工作:
EnableAspectJAutoProxy:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
可以看到注如了一个AspectJAutoProxyRegistrar 类型的 bean
AspectJAutoProxyRegistrar :
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
AspectJAutoProxyRegistrar() {
}
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// bean 的注册 ,注册 AnnotationAwareAspectJAutoProxyCreator 类型的bean
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
// 注册完成 获取EnableAspectJAutoProxy 的属性值 然后进行属性设置
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
AopConfigUtils registerAspectJAnnotationAutoProxyCreatorIfNecessary 对于切面的扫描:
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, (Object)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");
if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
} else {
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Integer.MIN_VALUE);
beanDefinition.setRole(2);
registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
return beanDefinition;
}
}
最终在创建某个bean 初始化之后会调用到父类AbstractAutoProxyCreator 的postProcessAfterInitialization 方法,判断改bean是否需要进行aop :
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 对创建的bean 进行包装
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
对bean 进行下包装:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
} else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
} else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
// 是否有切面的逻辑,由切面 需要进行aop
// 获取当前的bean 与存在的advisor 能够匹配上 ,对bean 的类进行匹配 获取到匹配的advisor
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
if (specificInterceptors != DO_NOT_PROXY) {
// 如果有匹配到的advisor 则需要进行aop
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 对当前的bean 创建代理对象,specificInterceptors 为代理逻辑advisor
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
isInfrastructureClass 进行是否有切面的逻辑:
protected boolean isInfrastructureClass(Class<?> beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) || Pointcut.class.isAssignableFrom(beanClass) || Advisor.class.isAssignableFrom(beanClass) || AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && this.logger.isTraceEnabled()) {
this.logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
}
2.2.2 获取spring 中所有的Advisor 与正在创建的bean 进行类和方法的匹配:
AbstractAdvisorAutoProxyCreator 下getAdvicesAndAdvisorsForBean 方法,匹配当前正在创建的bean 进而判断改bean 是否需要增加代理逻辑
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
// 获取代理的逻辑对象
List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName);
return advisors.isEmpty() ? DO_NOT_PROXY : advisors.toArray();
}
向下调用:
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 获取代理的逻辑对象
// 获取所有的advisor
List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
// 对advisor 进行筛选 对bean 的类型和 类中的所有方法,通过遍历的方式
// 依此和bean 类中的方法进行匹配,继而筛选出匹配的代理逻辑对象 advisor
List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
this.extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
// 对Advisor 进行排序,AspectJAwareAdvisorAutoProxyCreator 下的 sortAdvisors 对匹配改bean 的所有advisor 进行排序
// 方法 this.sortAdvisors(eligibleAdvisors) 是在 findEligibleAdvisors 方法流程中的一个步骤。
// 它将对找到的所有合适的advisor进行排序。排序的目的是为了确定通知(advice)的执行顺序。当存在多个advisor时,
// 它们定义的通知(如前置通知、后置通知等)可能会冲突或有特定的调用顺序要求。这个排序过程就是确保通知按照预定的顺序执行。
// 通常基于通知类型、优先级、切入点表达式等规则来决定每个advisor的顺序。
// 排序之后的advisor列表将被用来创建代理,每次方法调用时都会遵守这个确定的顺序来调用各个通知。
// 具体地,排序过程会依据 Advisor 接口或其实现子类的 getOrder 方法返回的值。这个值表明了执行顺序的优先级。
// 数字越低,优先级越高,意味着该advisor的通知将会优先于其他优先级高的advisor执行。
eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
2.2.2.1 findCandidateAdvisors 获取所有的Advisor:
AnnotationAwareAspectJAutoProxyCreator 下 findCandidateAdvisors 方法获取项目中所有的Advisor 对象:
protected List<Advisor> findCandidateAdvisors() {
// 通过spring 工厂获取获取所有的advisor类型的bean
List<Advisor> advisors = super.findCandidateAdvisors();
if (this.aspectJAdvisorsBuilder != null) {
// 解析@Aspect 中定义的方法
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
aspectJAdvisorsBuilder.buildAspectJAdvisors() 解析@Aspect:
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();
List<String> aspectNames = new ArrayList();
// 获取所有的bean
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
String[] var18 = beanNames;
int var19 = beanNames.length;
for(int var7 = 0; var7 < var19; ++var7) {
String beanName = var18[var7];
//
if (this.isEligibleBean(beanName)) {
// 获取bean 的类型
Class<?> beanType = this.beanFactory.getType(beanName, false);
if (beanType != null && this.advisorFactory.isAspect(beanType)) {
// 如果这个bean 是@Aspect 切面bean
aspectNames.add(beanName);
// 获取@Aspect 切面bean 的元数据
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);
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);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
} else {
List<Advisor> advisors = new ArrayList();
Iterator var3 = aspectNames.iterator();
while(var3.hasNext()) {
String aspectName = (String)var3.next();
List<Advisor> cachedAdvisors = (List)this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
} else {
MetadataAwareAspectInstanceFactory factory = (MetadataAwareAspectInstanceFactory)this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
}
this.advisorFactory.getAdvisors(factory) 对@Aspect 中的方法进行解析:
ReflectiveAspectJAdvisorFactory 下的getAdvisors
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
// 获取bean 的类型和名称
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
this.validate(aspectClass);
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList();
// 获取所有的advisor
Iterator var6 = this.getAdvisorMethods(aspectClass).iterator();
while(var6.hasNext()) {
// 遍历所有方法封装advisor
Method method = (Method)var6.next();
Advisor advisor = this.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);
}
Field[] var12 = aspectClass.getDeclaredFields();
int var13 = var12.length;
for(int var14 = 0; var14 < var13; ++var14) {
Field field = var12[var14];
Advisor advisor = this.getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
this.getAdvisorMethods 获取所有的advisor : this.getAdvisorMethods:获取所有没有加@Pointcut 注解的方法,对于没有@Before
等注解的普通方法也可以拿到
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
List<Method> methods = new ArrayList();
ReflectionUtils.doWithMethods(aspectClass, methods::add, adviceMethodFilter);
if (methods.size() > 1) {
// 排序 对多个注解进行排序
methods.sort(adviceMethodComparator);
}
return methods;
}
methods.sort 对于获取到的进行排序:
static {
adviceMethodFilter = ReflectionUtils.USER_DECLARED_METHODS.and((method) -> {
return AnnotationUtils.getAnnotation(method, Pointcut.class) == null;
});
// 先按照 注解排序,对于同一个注解按照方法的名字进行排序(字母排序)
Comparator<Method> adviceKindComparator = new ConvertingComparator(new InstanceComparator(new Class[]{Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class}), (method) -> {
AbstractAspectJAdvisorFactory.AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
return ann != null ? ann.getAnnotation() : null;
});
Comparator<Method> methodNameComparator = new ConvertingComparator(Method::getName);
adviceMethodComparator = adviceKindComparator.thenComparing(methodNameComparator);
}
this.getAdvisor 对切面中的方法封装为Advisor 对象:
@Nullable
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) {
this.validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
AspectJExpressionPointcut expressionPointcut = this.getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
// 如果改方法有@Before 等注解封装,则通过 InstantiationModelAwarePointcutAdvisorImpl 封装advisor
return expressionPointcut == null ? null : new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
this.getPointcut // 封装Pointcut
@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
// 当前方法是否有@Before 等的修饰
AbstractAspectJAdvisorFactory.AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
} else {
// 解析表达式 然后封装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;
}
}
InstantiationModelAwarePointcutAdvisorImpl 封装advisor:
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 PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
} else {
this.pointcut = this.declaredPointcut;
this.lazy = false;
// 对注解的方法进行解析
this.instantiatedAdvice = this.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;
}
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
//获取切面对象
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
this.validate(candidateAspectClass);
AbstractAspectJAdvisorFactory.AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
} else if (!this.isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: Offending method '" + candidateAdviceMethod + "' in class [" + candidateAspectClass.getName() + "]");
} else {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}
Object springAdvice;
// 对切面的方法进行解析
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (this.logger.isDebugEnabled()) {
this.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())) {
((AbstractAspectJAdvice)springAdvice).setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing)aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
((AbstractAspectJAdvice)springAdvice).setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException("Unsupported advice type on method: " + candidateAdviceMethod);
}
((AbstractAspectJAdvice)springAdvice).setAspectName(aspectName);
((AbstractAspectJAdvice)springAdvice).setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
((AbstractAspectJAdvice)springAdvice).setArgumentNamesFromStringArray(argNames);
}
((AbstractAspectJAdvice)springAdvice).calculateArgumentBindings();
return (Advice)springAdvice;
}
}
2.2.2.2 findAdvisorsThatCanApply 对找到的Advisor 进行筛选:
protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
List var4;
try {
// 对正在创建的bean 进行advisor 的匹配,返回 匹配到的Advisor,beanClass 为正在创建bean 的class 类型
var4 = AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
} finally {
ProxyCreationContext.setCurrentProxiedBeanName((String)null);
}
return var4;
}
AopUtils.findAdvisorsThatCanApply 对spring 中已经存在的Advisor 进行匹配:
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
} else {
List<Advisor> eligibleAdvisors = new ArrayList();
Iterator var3 = candidateAdvisors.iterator();
while(var3.hasNext()) {
Advisor candidate = (Advisor)var3.next();
// 通过 canApply 进行匹配 匹配通过放入到eligibleAdvisors 集合中
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
Iterator var7 = candidateAdvisors.iterator();
while(var7.hasNext()) {
Advisor candidate = (Advisor)var7.next();
if (!(candidate instanceof IntroductionAdvisor) && canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
}
canApply 匹配:
public static boolean canApply(Advisor advisor, Class<?> targetClass) {
return canApply(advisor, targetClass, false);
}
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 {
return true;
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
// 首先对正在创建的bean 的 类型做匹配
if (!pc.getClassFilter().matches(targetClass)) {
return false;
} else {
// 类型匹配完成,则进行方法的匹配
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
return true;
} else {
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));
Iterator var6 = classes.iterator();
while(var6.hasNext()) {
Class<?> clazz = (Class)var6.next();
// 获取改类的所有方法
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
Method[] var9 = methods;
int var10 = methods.length;
for(int var11 = 0; var11 < var10; ++var11) {
Method method = var9[var11];
if (introductionAwareMethodMatcher != null) {
// 遍历每个方法对当前传入的 advisor 进行匹配
if (introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) {
return true;
}
} else if (methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
}
}
至此为当前正在创建的bean 筛选出匹配改bean 的所有advisor ;
2.2.3 this.createProxy 创建代理对象:
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 proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (proxyFactory.isProxyTargetClass()) {
if (Proxy.isProxyClass(beanClass) || ClassUtils.isLambdaClass(beanClass)) {
Class[] var6 = beanClass.getInterfaces();
int var7 = var6.length;
for(int var8 = 0; var8 < var7; ++var8) {
Class<?> ifc = var6[var8];
proxyFactory.addInterface(ifc);
}
}
} else if (this.shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
this.evaluateProxyInterfaces(beanClass, proxyFactory);
}
// 获取代理逻辑
Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
// 设置被代理的对象
proxyFactory.setTargetSource(targetSource);
this.customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (this.advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
ClassLoader classLoader = this.getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader)classLoader).getOriginalClassLoader();
}
// 返回代理对象,最终代理对象,则最终执行被代理对象的方法时,对advisors
// 完成类和方法的筛选,进入到代理的逻辑
return proxyFactory.getProxy(classLoader);
}
三、扩展:
spring 中 aop 的 aspect 与aspect jar 包中的aspect 关系:
spring 仅仅使用了aspect 中的一些注解类;在aspect 中对aop 的支持是在代码编译期时就完成了代理逻辑的增强;
在spirng 中虽然使用aspect 的一些注解,但是注解 功能的具体实现时由spring 自身完成的;
在spring中为已经存在的bean 增加 @Aspect 注解后,他的解析过程为:首先这个类是一个bean ,在扫描这个bean 的时候发现它又是一个aspect 则通过特有的bean 对其中定义的方法件解析;将一个个表达式定义成为 pointCunt将注解定义的方法定义成为一个个advice ;进而完成代理逻辑的绑定;
总结
在Spring AOP(面向切面编程)中,AbstractAdvisorAutoProxyCreator 是自动代理创建器的一个抽象类,其主要职责是扫描Spring容器中的Bean,寻找那些需要创建代理对象的Bean(被称为advised bean),并为它们自动生成代理。
在创建代理时,AbstractAdvisorAutoProxyCreator 需要确定应用于每个Bean的通知(advice)和切面(aspect)。在这个过程中,findEligibleAdvisors 方法扮演了关键角色。这个方法负责寻找所有合适的advisor(即包含通知和切入点的对象)。一旦找到这些advisor,它们就可以被用来为目标Bean创建代理,并且在调用Bean的方法时执行相关的通知。
方法 this.sortAdvisors(eligibleAdvisors) 是在 findEligibleAdvisors 方法流程中的一个步骤。它将对找到的所有合适的advisor进行排序。排序的目的是为了确定通知(advice)的执行顺序。当存在多个advisor时,它们定义的通知(如前置通知、后置通知等)可能会冲突或有特定的调用顺序要求。这个排序过程就是确保通知按照预定的顺序执行。通常基于通知类型、优先级、切入点表达式等规则来决定每个advisor的顺序。排序之后的advisor列表将被用来创建代理,每次方法调用时都会遵守这个确定的顺序来调用各个通知。
具体地,排序过程会依据 Advisor 接口或其实现子类的 getOrder 方法返回的值。这个值表明了执行顺序的优先级。数字越低,优先级越高,意味着该advisor的通知将会优先于其他优先级高的advisor执行。
以上为spring 中为bean 增加切面逻辑的整体流程方法,具体的实现细节可以在项目里通过断点进行调试。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!