spring-源码-AOP使用

tech2024-05-08  81

文章目录

说明切面、通知、切入点 什么时候起作用接口SmartInstantiationAwareBeanPostProcessorInstantiationAwareBeanPostProcessorBeanPostProcessor说明 主流程resolveBeforeInstantiationpostProcessBeforeInstantiation Aspect 、Advice、Pointcut、AdvisorpostProcessBeforeInstantiationshouldSkipfindCandidateAdvisors(获取所有的增强器)buildAspectJAdvisorsgetAdvisors(获取所有增强器)getAdvisor(获取单个增强器)getPointcut(获取切入点)创建InstantiationModelAwarePointcutAdvisorImpl(通知和增强器)instantiateAdvice(初始化通知)getAdvice(获取通知) getCustomTargetSource说明 处理Weaving、Joinpoint、Proxy、Target分析 postProcessAfterInitializationwrapIfNecessary(包装目标类,如果需要的话)getAdvicesAndAdvisorsForBeanfindEligibleAdvisors(找到合适的增强器)findAdvisorsThatCanApply(找到能够应用的增强器)findAdvisorsThatCanApply(找到能够应用的增强器)canApply(能够应用的增强器)canApply(能够应用的增强器)getClassFilter(获取切点表达式)obtainPointcutExpression(获取切入点表达式)buildPointcutExpressionresolveExpressionreplaceBooleanOperatorsparsePointcutExpression matches(匹配当前类)couldMatchJoinPointsInType(判断当前类是否可以匹配切入点) 说明 createProxygetProxycreateAopProxycreateAopProxygetProxy

说明

本文,从代码来解析AOP的一些概念、源码、流程等…

首先需要对spring AOP 的一些概念需要有一些了解…

Aspect (切面)Advice(通知)Pointcut(切入点)Advisor(增强器、顾问)我比较喜欢称之为增强器,如果注释中存在增强器指的就是这个…Target (目标对象)

切面、通知、切入点

简单说,一个切面定义了 切入点和通知

而 Advisor(顾问、增强器)将切面的里面的 切入点和通知进行了一个包装

什么时候起作用

也就说 我们的AOP 什么时候去使用的?我们知道 当一个Bean注册的时候会对Bean 做一些列操作 ,简单说也就是 相关 BeanPostProcessor,而我们通过接口分析得知AnnotationAwareAspectJAutoProxyCreator最终是实现了SmartInstantiationAwareBeanPostProcessor、InstantiationAwareBeanPostProcessor也就是说基本是 执行 BeanPostProcessor的时候去进行处理的,在通过源码了解到 BeanPostProcessor 是贯穿了我们 Bean 的生命周期的,那其实我们想知道这个什么时候起的作用,只需要知道实现的这几个方法什么时候执行的即可

接口

单从结果上看 仅仅只有 AbstractAutoProxyCreator 去实现了这些方法,子类并没有重新和覆盖

SmartInstantiationAwareBeanPostProcessor

predictBeanTypedetermineCandidateConstructorsgetEarlyBeanReference

InstantiationAwareBeanPostProcessor

postProcessBeforeInstantiationpostProcessAfterInstantiationpostProcessPropertiespostProcessPropertyValues

调用时机可参考 InstantiationAwareBeanPostProcessor

由AbstractAutoProxyCreator 去实现了这些方法

BeanPostProcessor

postProcessBeforeInitializationpostProcessAfterInitialization

调用时机可参考 BeanPostProcessor

由 AbstractAutoProxyCreator去实现了这些方法

说明

当创建一个 Bean 的时候,也就说只有2个地方可能会返回代理对象,一个是直接返回代理对象,根本不给机会去创建对象,另一个是走完初始化方法调用后返回代理对象

主流程

主流程指的是DBUG线程调用的地方方法~~,也就说每一次的Bean 创建都会走这里…

refresh();finishBeanFactoryInitialization(beanFactory);beanFactory.preInstantiateSingletons();getBean(beanName);doGetBean()getSingleton()createBean()

resolveBeforeInstantiation

给 BeanPostProcessors 一个 机会 返回 一个代理替换这个目标 Bean 的 实例,简单来说,直接就通过代理返回结果了

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; // beforeInstantiationResolved 可能是 null 、true、false // null 代表 bean 没有走过 resolveBeforeInstantiation 这个方法 // true 代表 bean 已经走过 resolveBeforeInstantiation 这个方法 // false 代表 bean 不需要走 resolveBeforeInstantiation 这个方法 // 这里是为了一个效率的存在,当如果 这个 BeanDefinition 已经走过一边后,并且返回了 false 后下次就不会继续走了 if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // 1. 判断是不是 合成 Bean // 2. 判断有没有 实现了 InstantiationAwareBeanPostProcessor 这个接口的 BeanPostProcessors if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { // 执行前置方法 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); // 如果不是 null 就代表已经返回对象了,则会去执行后置方法 if (bean != null) { // 执行后置方法 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } // bean != null 返回 true 代表 bean 已经被创建 // bean != null 返回 false 代表 bean 不需要进行代理.. mbd.beforeInstantiationResolved = (bean != null); } return bean; }

这里可以看到一个细节就是 BeanDefinition. beforeInstantiationResolved 这个属性 是为了缓存结果,简单来说当走完所有的 InstantiationAwareBeanPostProcessors 后如果都是不创建那就会定义为 false,也就是说在 多例(原型)的情况下这里的代码如果第一次走完后,下次如果是false就会直接返回.

postProcessBeforeInstantiation

Aspect 、Advice、Pointcut、Advisor

这里简单说就是获取增强器,可以通过XML、接口、注解方式进行配置,来让我们一步一步的将他吃透…大致是这些流程…

postProcessBeforeInstantiation

AbstractAutoProxyCreator.postProcessBeforeInstantiation

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) { // 获取 一个用于缓存 key 其实就是 BeanName Object cacheKey = getCacheKey(beanClass, beanName); // 判断 targetSourcedBeans 不包含这个 bean if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { // 判断需要增强的 Bean 是否包含这个 Bean // advisedBeans 包含所有 切面Bean 和 增强Bean if (this.advisedBeans.containsKey(cacheKey)) { return null; } //1. 判断是不是 基础类型,也就说判断是不是 实现了这些接口 Advice、Pointcut、Advisor、AopInfrastructureBean、 //2. 还会判断是不是 有没有 @Aspect 注解 // isInfrastructureClass 执行方法,主要注意的是 this 的指向是 AnnotationAwareAspectJAutoProxyCreator, // 所以执行 AnnotationAwareAspectJAutoProxyCreator.isInfrastructureClass() // 这段逻辑是处理如果是基础类、切面类、原始类 都不会进行代理 if (isInfrastructureClass(beanClass) || // 所以执行 AnnotationAwareAspectJAutoProxyCreator.shouldSkip() // 判断是不是需要跳过,如果返回true则就会将 这个 name 进行缓存 shouldSkip(beanClass, beanName)) { // 这里其实是将 切面 Bean 的BeanName 缓存起来,代表这个 Bean 不进行 增强操作 this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } // 如果我们有自定义的TargetSource,请在此处创建代理。 // 禁止目标Bean的不必要的默认实例化: TargetSource 将以自定义方式处理目标实例。 TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { // 这个 BeanName 是正常的 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; }

shouldSkip

isInfrastructureClass 执行方法,主要注意的是 this 的指向是 AbstractAutoProxyCreator, 所以会执行AnnotationAwareAspectJAutoProxyCreator.shouldSkip()

protected boolean shouldSkip(Class<?> beanClass, String beanName) { // 找到候选的 增强器,也就是说是切面里面的通知方法 List<Advisor> candidateAdvisors = findCandidateAdvisors(); // 循环所有 增强器 for (Advisor advisor : candidateAdvisors) { //判断我们的增强器是不是 AspectJPointcutAdvisor 这个类型 if (advisor instanceof AspectJPointcutAdvisor && // 并且 增强的名称和我们的BeanName 是一致 ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) { return true; } } // 这里基本返回 false.. return super.shouldSkip(beanClass, beanName); } // 父类的方法 protected boolean shouldSkip(Class<?> beanClass, String beanName) { // 判断是不是 原始的实例,也就是说是不需要进行代理的实例 return AutoProxyUtils.isOriginalInstance(beanName, beanClass); } static boolean isOriginalInstance(String beanName, Class<?> beanClass) { // 如果 BeanName 不正常 返回 false // beanName 的长度不是 bean全限定类名+ ORIGINAL_INSTANCE_SUFFIX(原始后缀),也返回 false // 也就是说这里基本会返回 false 那什么时候返回 True 呢 当我们的Bean 是全限定类名 + ORIGINAL_INSTANCE_SUFFIX 的时候... // 这里可以去手动注册一个 这样的Bean,演示DEMO 在下面~~~ if (!StringUtils.hasLength(beanName) || beanName.length() != beanClass.getName().length() + AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX.length()) { return false; } return (beanName.startsWith(beanClass.getName()) && beanName.endsWith(AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX)); } //-----------------------------DEMO // @EnableAspectJAutoProxy // @ComponentScan // public class IsOriginalInstanceContext { // public static void main(String[] args) { // AnnotationConfigApplicationContext value = new AnnotationConfigApplicationContext(); // value.register(IsOriginalInstanceContext.class); // value.registerBeanDefinition(IsOriginalInstanceBean.class.getName() // + AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX, // BeanDefinitionBuilder.genericBeanDefinition(IsOriginalInstanceBean.class).getBeanDefinition() // ); // value.refresh(); // } // } //----------------------------

findCandidateAdvisors(获取所有的增强器)

这里也是同理,会调用AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors()

这里逻辑分为两步

调用父类的findCandidateAdvisors()方法获取的是 实现了 Advisor 接口的Bean获取的是注解 切面里面所有的 Advisor protected List<Advisor> findCandidateAdvisors() { // 获取所有 实现 Advisor 接口的类,这里的代码就不贴了.. 自己可以去看看比如自己转配一个 Bean 去实现这个 Advisor 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; }

buildAspectJAdvisors

public List<Advisor> buildAspectJAdvisors() { // 因为解析会很消耗性能,所以 Spring 会使用 aspectBeanNames 保存解析结果 List<String> aspectNames = this.aspectBeanNames; // 如果==null 代表没处理过,因为第二次肯定不为 null,在 进入这个条件后,就会创建 ArrayList if (aspectNames == null) { // 进行加锁处理,防止多线程情况下一起操作解析 synchronized (this) { // 二次赋值,防治以及操作过了 aspectNames = this.aspectBeanNames; //双重非空判断,避免再次解析 if (aspectNames == null) { List<Advisor> advisors = new ArrayList<>(); // 创建切面集合 aspectNames = new ArrayList<>(); // 查找所有的 BeanName 包括父类 String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Object.class, true, false); for (String beanName : beanNames) { //排除不合法的ban,由子类定义规则,默认返回true if (!isEligibleBean(beanName)) { continue; } // 根据Name获取Class类型 Class<?> beanType = this.beanFactory.getType(beanName); if (beanType == null) { continue; } // 判断 是否存在 @Aspect 注解 并且判断 目标类上所有的属性不包含 "ajc$" if (this.advisorFactory.isAspect(beanType)) { // 将 切面的 BeanName 放入到集合中 aspectNames.add(beanName); // 包装成 AspectMetadata AspectMetadata amd = new AspectMetadata(beanType, beanName); //检查 @Aspect 注解的value值,验证生成的增强是否是单例 if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { // 创建一个工厂.. MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); // 获取标记 Aspect 注解的增强方法 List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); //如果bean是单例,则缓存bean的增强器 if (this.beanFactory.isSingleton(beanName)) { // 将 切面 BeanName 和 增强器 进行缓存 this.advisorsCache.put(beanName, classAdvisors); } // bean非单例,只缓存bean对应的增强器创建工厂 else { this.aspectFactoryCache.put(beanName, factory); } // 将获取的 增强器 放入到集合中 advisors.addAll(classAdvisors); } else { // 切面创建模式非单例,这里的Else 基本不会进来... // 如果切面是非单例,但是bean是单例,抛出异常 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)); } } } //将已经解析过的切面 Bean 进行缓存 this.aspectBeanNames = aspectNames; return advisors; } } } // 如果是 null 就会直接返回... if (aspectNames.isEmpty()) { // 如果是一个空的就返回一个空集合 return Collections.emptyList(); } List<Advisor> advisors = new ArrayList<>(); // 循环 切面的Name for (String aspectName : aspectNames) { // 根据切面的Name 获取 增强器 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; }

getAdvisors(获取所有增强器)

public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { // 获取 切面的 Class Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); // 获取 切面的 Name 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)) { // Prior to Spring Framework 5.2.7, advisors.size() was supplied as the declarationOrderInAspect // to getAdvisor(...) to represent the "current position" in the declared methods list. // However, since Java 7 the "current position" is not valid since the JDK no longer // returns declared methods in the order in which they are declared in the source code. // Thus, we now hard code the declarationOrderInAspect to 0 for all advice methods // discovered via reflection in order to support reliable advice ordering across JVM launches. // Specifically, a value of 0 aligns with the default value used in // AspectJPrecedenceComparator.getAspectDeclarationOrder(Advisor). // 尝试解析每个方法,找到方法对应的切点和通知 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); } // 处理 @DeclareParents 注解 for (Field field : aspectClass.getDeclaredFields()) { Advisor advisor = getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } } return advisors; }

getAdvisor(获取单个增强器)

从这里可以看出 Advisor 指的就是 切入点和通知的集合

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 的时候 里面有一个 instantiateAdvice--> getAdvice 比较重要需要看一下 // 将切入点和通知包装成一个 增强器 return new InstantiationModelAwarePointcutAdvisorImpl( expressionPointcut, //切入点表达式 candidateAdviceMethod, //通知方法 this, aspectInstanceFactory, // 切面实例的工厂.. declarationOrderInAspect, //0 aspectName //切面名称 ); }

getPointcut(获取切入点)

获取Pointcut(切入点),需要说明的是这里如果使用的 @Pointcut 定义的切入点… 并没有进行解析,简单说 AspectJExpressionPointcut 的 Pointcut 仅仅是 @Pointcut的方法名…

@Nullable private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) { // 获取方法的(通知) // Pointcut.class, // Around.class, // Before.class, // After.class, // AfterReturning.class, // AfterThrowing.class AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); if (aspectJAnnotation == null) { return null; } // 构建一个 切点 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; }

1

创建InstantiationModelAwarePointcutAdvisorImpl(通知和增强器)

public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut, Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { // 精简代码.... // 如果是懒加载 if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { // 这里不用太关注. } else { // A singleton aspect. this.pointcut = this.declaredPointcut; this.lazy = false; this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut); } }

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

getAdvice(获取通知)

public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { //切面类 带有@Aspect注解的类 Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); validate(candidateAspectClass); // 获取方法的(通知)来确认当前方法是具体的那个类型的通知 // Pointcut.class, // Around.class, // Before.class, // After.class, // AfterReturning.class, // AfterThrowing.class AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); if (aspectJAnnotation == null) { return null; } //再去校验一遍 如果不是切面类 则抛出异常 if (!isAspect(candidateAspectClass)) { throw new AopConfigException(""); } 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; //如果是前置通知,则直接创建AspectJMethodBeforeAdvice实例 //入参为:通知方法、切点表达式、切面实例 case AtBefore: springAdvice = new AspectJMethodBeforeAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; //如果是后置通知,则直接创建AspectJAfterAdvice实例 //入参为:通知方法、切点表达式、切面实例 case AtAfter: springAdvice = new AspectJAfterAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; //如果是后置返回通知,则直接创建AspectJAfterReturningAdvice实例 //入参为:通知方法、切点表达式、切面实例 case AtAfterReturning: springAdvice = new AspectJAfterReturningAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation(); //设置后置返回值的参数name if (StringUtils.hasText(afterReturningAnnotation.returning())) { springAdvice.setReturningName(afterReturningAnnotation.returning()); } break; //如果是后置异常通知,则直接创建AspectJAfterThrowingAdvice实例 //入参为:通知方法、切点表达式、切面实例 case AtAfterThrowing: springAdvice = new AspectJAfterThrowingAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation(); //设置后置异常通知 异常类型参数name if (StringUtils.hasText(afterThrowingAnnotation.throwing())) { springAdvice.setThrowingName(afterThrowingAnnotation.throwing()); } break; default: throw new UnsupportedOperationException( "Unsupported advice type on method: " + candidateAdviceMethod); } // 切面的名字 springAdvice.setAspectName(aspectName); springAdvice.setDeclarationOrder(declarationOrder); // 通知注解中的参数名,换而言之就是获取 通知注解中的 argNames 属性 String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod); if (argNames != null) { springAdvice.setArgumentNamesFromStringArray(argNames); } //计算argNames和类型的对应关系 springAdvice.calculateArgumentBindings(); return springAdvice; }

getCustomTargetSource

这个单独领出来说,是这里…想要进入条件比较刻薄

protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) { // customTargetSourceCreators 不为空 // beanFactory 不为空 // bean 存在 spring容器中 if (this.customTargetSourceCreators != null && this.beanFactory != null && this.beanFactory.containsBean(beanName)) { for (TargetSourceCreator tsc : this.customTargetSourceCreators) { TargetSource ts = tsc.getTargetSource(beanClass, beanName); if (ts != null) { // Found a matching TargetSource. if (logger.isTraceEnabled()) { logger.trace("TargetSourceCreator [" + tsc + "] found custom TargetSource for bean with name '" + beanName + "'"); } return ts; } } } // No custom TargetSource found. return null; }

说明

整个上面的所有代码都是获取 Aspect 和 Advice 和 Pointcut

缓存了 实现了 Advisor 接口 Bean 的name缓存了 @Aspect 注解的 Bean 的name缓存了 切面 Bean 下面的所有 Advisor(Advice、Pointcut)

为什么这么做… 为了效率,因为每一次都会去拦截,每次都会去走一遍,对其数据进行缓存,其实随处可见的细节太多了…

处理Weaving、Joinpoint、Proxy、Target

根据主流程~~ 继续DBUG,也就是说没有直接返回代理对象~~这里的代码就不贴了,直接贴核心代码

doCreateBeaninitializeBeanapplyBeanPostProcessorsAfterInitialization

分析 postProcessAfterInitialization

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { // 判断这个对象是否创建成功.. if (bean != null) { // 获取一个 key ,用于缓存.. Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { // 这里就是去搞代理去了 return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }

wrapIfNecessary(包装目标类,如果需要的话)

这里的细节点是 可以看到 advisedBeans.put(cacheKye,Boolean.FALSE) 或者ture ,其实为了就是效率…

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { // 判断 beanName是正常的 并且 targetSourcedBeans 已经存在则会直接返回 if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } //判断 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; } // Create proxy if we have advice. // 创建代理对象 // 1. 获取当前Bean 的所有增强器(通知方法) Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); // 如果不是 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; } // 如果不需要代理则设置为 False 当下次进来的时候会直接返回(细节) this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }

getAdvicesAndAdvisorsForBean

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

findEligibleAdvisors(找到合适的增强器)

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { //获取所有的增强器,这里之前已经分析过了就不分析了.. List<Advisor> candidateAdvisors = findCandidateAdvisors(); //找到适合的增强器 List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { // 对增强器进行 排序 eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }

findAdvisorsThatCanApply(找到能够应用的增强器)

protected List<Advisor> findAdvisorsThatCanApply( List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) { ProxyCreationContext.setCurrentProxiedBeanName(beanName); try { // 返回当前Bean能用的增强器 return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); } finally { ProxyCreationContext.setCurrentProxiedBeanName(null); } }

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(); // 循环所有的增强器 for (Advisor candidate : candidateAdvisors) { //判断如果是这个类型的就跳过,因为上个循环已经处理过了 if (candidate instanceof IntroductionAdvisor) { // already processed continue; } // 判断是不是能用的增强器,如果是能用的则添加到集合当中去 if (canApply(candidate, clazz, hasIntroductions)) { eligibleAdvisors.add(candidate); } } return eligibleAdvisors; }

canApply(能够应用的增强器)

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

canApply(能够应用的增强器)

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) { Assert.notNull(pc, "Pointcut must not be null"); // 这一步会去解析 切入点表达式... 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<>(); // 判断是否是 Proxy 的子类并且 proxyClassCache 存在 这个类 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; }

getClassFilter(获取切点表达式)

解析切入点表达式…为过滤做准备

public ClassFilter getClassFilter() { obtainPointcutExpression(); return this; }

obtainPointcutExpression(获取切入点表达式)

private PointcutExpression obtainPointcutExpression() { // 如果表达式不存在 抛出异常... if (getExpression() == null) { throw new IllegalStateException("Must set property 'expression' before attempting to match"); } // 如果 切入点表达式 是null 去进行解析,因为我们的表达式可能是 通过@Pointcut 的方式 if (this.pointcutExpression == null) { this.pointcutClassLoader = determinePointcutClassLoader(); this.pointcutExpression = buildPointcutExpression(this.pointcutClassLoader); } return this.pointcutExpression; }

buildPointcutExpression

去解析表达式…

private PointcutExpression buildPointcutExpression(@Nullable ClassLoader classLoader) { // 初始化基础的Aspect切入点解析器 PointcutParser parser = initializePointcutParser(classLoader); // 获取切入点参数... PointcutParameter[] pointcutParameters = new PointcutParameter[this.pointcutParameterNames.length]; for (int i = 0; i < pointcutParameters.length; i++) { // 将参数和类型包装一下 放入到数组中 pointcutParameters[i] = parser.createPointcutParameter( this.pointcutParameterNames[i], this.pointcutParameterTypes[i]); } // 这里嵌套了3个方法....而且还异常复杂我都不忍心看... return parser.parsePointcutExpression(replaceBooleanOperators(resolveExpression()), this.pointcutDeclarationScope, pointcutParameters); }

resolveExpression

private String resolveExpression() { // 获取表达式 String expression = getExpression(); Assert.state(expression != null, "No expression set"); // 返回表达式 return expression; }

replaceBooleanOperators

private String replaceBooleanOperators(String pcExpr) { // 将表达式中的 and 替换 String result = StringUtils.replace(pcExpr, " and ", " && "); // 将表达式中的 or 替换 result = StringUtils.replace(result, " or ", " || "); // 将表达式中的 not 替换 result = StringUtils.replace(result, " not ", " ! "); return result; }

parsePointcutExpression

public PointcutExpression parsePointcutExpression(String expression, Class<?> inScope, PointcutParameter[] formalParameters) throws UnsupportedPointcutPrimitiveException, IllegalArgumentException { PointcutExpressionImpl pcExpr = null; try { // 这里是对表达式的进行处理,具体的可以自己深究去 Pointcut pc = resolvePointcutExpression(expression, inScope, formalParameters); // 将表达式具体化,比如我使用的是 @Before("方法()") 这里是去将 "方法()" 转换成具体的 表达式 pc = concretizePointcutExpression(pc, inScope, formalParameters); // again, because we have now followed any ref'd pcuts validateAgainstSupportedPrimitives(pc, expression); // 包装成 对象返回 pcExpr = new PointcutExpressionImpl(pc, expression, formalParameters, getWorld()); } catch (ParserException pEx) { throw new IllegalArgumentException(buildUserMessageFromParserException(expression, pEx)); } catch (ReflectionWorld.ReflectionWorldException rwEx) { throw new IllegalArgumentException(rwEx.getMessage()); } return pcExpr; }

matches(匹配当前类)

public boolean matches(Class<?> targetClass) { // 这里是去获取 切入点表达式.. 也包括了解析(这里其实在 getClassFilter) 已经解析过了~~ PointcutExpression pointcutExpression = obtainPointcutExpression(); try { try { //根据表达式的解析实例,验证此类是否匹配 return pointcutExpression.couldMatchJoinPointsInType(targetClass); } catch (ReflectionWorldException ex) { logger.debug("PointcutExpression matching rejected target class - trying fallback expression", ex); // Actually this is still a "maybe" - treat the pointcut as dynamic if we don't know enough yet PointcutExpression fallbackExpression = getFallbackPointcutExpression(targetClass); if (fallbackExpression != null) { return fallbackExpression.couldMatchJoinPointsInType(targetClass); } } } catch (Throwable ex) { logger.debug("PointcutExpression matching rejected target class", ex); } return false; }

couldMatchJoinPointsInType(判断当前类是否可以匹配切入点)

这里仅仅是去匹配当前类是否符合规则

public boolean couldMatchJoinPointsInType(Class aClass) { ResolvedType matchType = world.resolve(aClass.getName()); if (matchType.isMissing() && (world instanceof ReflectionWorld)) { // Class is a generated class that cannot be 'looked up' via getResource. // For example a proxy or lambda. // Use the class itself in this case matchType = ((ReflectionWorld)world).resolveUsingClass(aClass); } ReflectionFastMatchInfo info = new ReflectionFastMatchInfo(matchType, null, this.matchContext, world); //根据切入点和 目标类,判断类 package 是否匹配 boolean couldMatch = pointcut.fastMatch(info).maybeTrue(); return couldMatch; }

说明

上面一大串代码都是为了去进行匹配,当匹配成功的时候才会去创建代理对象

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 = new ProxyFactory(); // 将当前类的一些配置进行 复制 ,简单来说就是获取 XML 或者注解配置的属性.. // 这里可以参考一下: proxyFactory.copyFrom(this); // 判断是否是通过接口 默认是 False if (!proxyFactory.isProxyTargetClass()) { //根据最开始@EnableAspectJAutoProxy注解中的proxyTargetClass参数判断是否应该使用cglib代理 if (shouldProxyTargetClass(beanClass, beanName)) { //标识 使用cglib动态代理 proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } // 获取到增强器 Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); // 放入到 代理工厂 proxyFactory.addAdvisors(advisors); // 设置 目标 对象 proxyFactory.setTargetSource(targetSource); // 留个子类去实现的一个方法,也就是说我们可以通过重写这个方法进行定制 customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } return proxyFactory.getProxy(getProxyClassLoader()); }

getProxy

public Object getProxy(@Nullable ClassLoader classLoader) { // createAopProxy() 获取AOP 工厂判断 CGlib还是JDK return createAopProxy().getProxy(classLoader); }

createAopProxy

protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } // 获取到 AOP 代理工厂 // 然后判断 是 Cglib 还是JDK return getAopProxyFactory().createAopProxy(this); }

createAopProxy

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (!IN_NATIVE_IMAGE && (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) { // optimize 默认是 false // ProxyTargetClass 默认是 false // hasNoUserSuppliedProxyInterfaces 被代理的类没有实现接口 // 获取目标 Class Class<?> targetClass = config.getTargetClass(); // 判断当前类是不是接口 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }

getProxy

取决于 createAopProxy 返回的是 CGlib 还是JDK 代理

最新回复(0)