怎么做类似淘宝的网站,做游戏开箱网站的法律风险,vi设计案例网站,如何利用网站模板做网站一、前言 我们在上一节中已经介绍了Advisor的创建过程#xff0c;当时我们创建的logUtil这bean#xff0c;他在
resolveBeforeInstantiation返回的是null#xff0c;那么就会继续往下执行doCreateBean方法。
二、源码分析 protected Object doCreateBean(String beanName,…一、前言 我们在上一节中已经介绍了Advisor的创建过程当时我们创建的logUtil这bean他在
resolveBeforeInstantiation返回的是null那么就会继续往下执行doCreateBean方法。
二、源码分析 protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.// 这个beanWrapper是用来持有创建出来的bean对象的BeanWrapper instanceWrapper null;// 获取factoryBean实例缓存if (mbd.isSingleton()) {// 如果是单例对象从factorybean实例缓存中移除当前bean定义信息instanceWrapper this.factoryBeanInstanceCache.remove(beanName);}// 没有就创建实例if (instanceWrapper null) {// 根据执行bean使用对应的策略创建新的实例如工厂方法构造函数主动注入、简单初始化instanceWrapper createBeanInstance(beanName, mbd, args);}// 从包装类中获取原始beanObject bean instanceWrapper.getWrappedInstance();// 获取具体的bean对象的Class属性Class? beanType instanceWrapper.getWrappedClass();// 如果不等于NullBean类型那么修改目标类型if (beanType ! NullBean.class) {mbd.resolvedTargetType beanType;}// Allow post-processors to modify the merged bean definition.// 允许beanPostProcessor去修改合并的beanDefinitionsynchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {// MergedBeanDefinitionPostProcessor后置处理器修改合并bean的定义applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,Post-processing of merged bean definition failed, ex);}mbd.postProcessed true;}}// Eagerly cache singletons to be able to resolve circular references// even when triggered by lifecycle interfaces like BeanFactoryAware.// 判断当前bean是否需要提前曝光单例允许循环依赖当前bean正在创建中检测循环依赖boolean earlySingletonExposure (mbd.isSingleton() this.allowCircularReferences isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace(Eagerly caching bean beanName to allow for resolving potential circular references);}// 为避免后期循环依赖可以在bean初始化完成前将创建实例的ObjectFactory加入工厂addSingletonFactory(beanName, () - getEarlyBeanReference(beanName, mbd, bean));// //只保留二级缓存不向三级缓存中存放对象
// earlySingletonObjects.put(beanName,bean);
// registeredSingletons.add(beanName);
//
// synchronized (this.singletonObjects) {
// if (!this.singletonObjects.containsKey(beanName)) {
// //实例化后的对象先添加到三级缓存中三级缓存对应beanName的是一个lambda表达式(能够触发创建代理对象的机制)
// this.singletonFactories.put(beanName, () - getEarlyBeanReference(beanName, mbd, bean));
// this.registeredSingletons.add(beanName);
// }
// }}// Initialize the bean instance.// 初始化bean实例Object exposedObject bean;try {// 对bean的属性进行填充将各个属性值注入其中可能存在依赖于其他bean的属性则会递归初始化依赖的beanpopulateBean(beanName, mbd, instanceWrapper);// 执行初始化逻辑exposedObject initializeBean(beanName, exposedObject, mbd);}catch (Throwable ex) {if (ex instanceof BeanCreationException beanName.equals(((BeanCreationException) ex).getBeanName())) {throw (BeanCreationException) ex;}else {throw new BeanCreationException(mbd.getResourceDescription(), beanName, Initialization of bean failed, ex);}}if (earlySingletonExposure) {// 从缓存中获取具体的对象Object earlySingletonReference getSingleton(beanName, false);// earlySingletonReference只有在检测到有循环依赖的情况下才会不为空if (earlySingletonReference ! null) {// 如果exposedObject没有在初始化方法中被改变也就是没有被增强if (exposedObject bean) {exposedObject earlySingletonReference;}else if (!this.allowRawInjectionDespiteWrapping hasDependentBean(beanName)) {String[] dependentBeans getDependentBeans(beanName);SetString actualDependentBeans new LinkedHashSet(dependentBeans.length);for (String dependentBean : dependentBeans) {// 返回false说明依赖还没实例化好if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}// 因为bean创建后所依赖的bean一定是已经创建的// actualDependentBeans不为空则表示当前bean创建后其依赖的bean却没有全部创建完也就是说存在循环依赖if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,Bean with name beanName has been injected into other beans [ StringUtils.collectionToCommaDelimitedString(actualDependentBeans) ] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using getBeanNamesForType with the allowEagerInit flag turned off, for example.);}}}}// Register bean as disposable.try {// 注册bean对象方便后续在容器销毁的时候销毁对象registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, Invalid destruction signature, ex);}return exposedObject;} 然后就会进入到 initializeBean进行bean的初始化我们之前都知道在这个initializeBean会会执行BPP的after方法然后我们之前解析AOP配置文件的时候注入的AutoProxyCreator他是一个BeanPostProcessor这里会执行它的after方法来判断是否需要创建代理对象我们继续往下跟。
/*** 初始化给定的bean实例应用工厂回调以及init方法和BeanPostProcessors** Initialize the given bean instance, applying factory callbacks* as well as init methods and bean post processors.* pCalled from {link #createBean} for traditionally defined beans,* and from {link #initializeBean} for existing bean instances.* param beanName the bean name in the factory (for debugging purposes)* param bean the new bean instance we may need to initialize* param mbd the bean definition that the bean was created with* (can also be {code null}, if given an existing bean instance)* return the initialized bean instance (potentially wrapped)* see BeanNameAware* see BeanClassLoaderAware* see BeanFactoryAware* see #applyBeanPostProcessorsBeforeInitialization* see #invokeInitMethods* see #applyBeanPostProcessorsAfterInitialization*/protected Object initializeBean(String beanName, Object bean, Nullable RootBeanDefinition mbd) {// 如果安全管理器不为空if (System.getSecurityManager() ! null) {// 以特权的方式执行回调bean中的Aware接口方法AccessController.doPrivileged((PrivilegedActionObject) () - {invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());}else {// Aware接口处理器调用BeanNameAware、BeanClassLoaderAware、beanFactoryAwareinvokeAwareMethods(beanName, bean);}Object wrappedBean bean;//如果mdb不为null || mbd不是synthetic。一般是指只有AOP相关的prointCut配置或者Advice配置才会将 synthetic设置为trueif (mbd null || !mbd.isSynthetic()) {// 将BeanPostProcessors应用到给定的现有Bean实例调用它们的postProcessBeforeInitialization初始化方法。// 返回的Bean实例可能是原始Bean包装器wrappedBean applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {//调用初始化方法先调用bean的InitializingBean接口方法后调用bean的自定义初始化方法invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {//捕捉调用初始化方法时抛出的异常重新抛出Bean创建异常调用初始化方法失败throw new BeanCreationException((mbd ! null ? mbd.getResourceDescription() : null),beanName, Invocation of init method failed, ex);}//如果mbd为null || mbd不是syntheticif (mbd null || !mbd.isSynthetic()) {// 将BeanPostProcessors应用到给定的现有Bean实例调用它们的postProcessAfterInitialization方法。// 返回的Bean实例可能是原始Bean包装器wrappedBean applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}//返回包装后的Beanreturn wrappedBean;} 我们继续往里面跟AutoProxyCretor的after方法看里面具体的执行逻辑。 Overridepublic Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {//初始化结果对象为result默认引用existingBeanObject result existingBean;//遍历该工厂创建的bean的BeanPostProcessors列表for (BeanPostProcessor processor : getBeanPostProcessors()) {//回调BeanPostProcessor#postProcessAfterInitialization来对现有的bean实例进行包装Object current processor.postProcessAfterInitialization(result, beanName);//一般processor对不感兴趣的bean会回调直接返回result使其能继续回调后续的BeanPostProcessor// 但有些processor会返回null来中断其后续的BeanPostProcessor// 如果current为nullif (current null) {//直接返回result中断其后续的BeanPostProcessor处理return result;}//让result引用processor的返回结果,使其经过所有BeanPostProcess对象的后置处理的层层包装result current;}//返回经过所有BeanPostProcess对象的后置处理的层层包装后的resultreturn result;} AbstractAutoProxyCreator的postProcessAfterInitialization方法。他里面会调用具体的wrapIfNecessary来判断是否要创建代理对象。 Overridepublic Object postProcessAfterInitialization(Nullable Object bean, String beanName) {if (bean ! null) {// 获取当前bean的key如果beanName不为空则以beanName为key如果为FactoryBean类型// 前面还会添加符号如果beanName为空则以当前bean对应的class为keyObject cacheKey getCacheKey(bean.getClass(), beanName);// 判断当前bean是否正在被代理如果正在被代理则不进行封装if (this.earlyProxyReferences.remove(cacheKey) ! bean) {// 如果它需要被代理则需要封装指定的beanreturn wrapIfNecessary(bean, beanName, cacheKey);}}return bean;} 这里的前面判断逻辑是跟之前是一样首先会在缓存里面判断当前bean是否已经被处理过很明显我们当前的logUtil之前已经被解析过并且放入到了缓存中因为我们的logUtil他是一个切面逻辑他不需要被创建代理对象。 其次会判断当前的bean是否是基础bean如果是则不用创建带来对象如果不是则会去盗用shouldSkip方法来判断当前的bean是否需要被跳过而在这这个shouldSkip方法中我们知道会寻找容器中的advisor对象。
/*** 先判断是否已经处理过是否需要跳过跳过的话直接就放进advisedBeans里表示不进行代理如果这个bean处理过了获取通知拦截器然后开始进行代理** Wrap the given bean if necessary, i.e. if it is eligible for being proxied.* param bean the raw bean instance* param beanName the name of the bean* param cacheKey the cache key for metadata access* return a proxy wrapping the bean, or the raw bean instance as-is*/protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {// 如果已经处理过直接返回if (StringUtils.hasLength(beanName) this.targetSourcedBeans.contains(beanName)) {return bean;}// 这里advisedBeans缓存了已经进行了代理的bean如果缓存中存在则可以直接返回if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {return bean;}// 这里isInfrastructureClass()用于判断当前bean是否为Spring系统自带的bean自带的bean是// 不用进行代理的shouldSkip()则用于判断当前bean是否应该被略过if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {// 对当前bean进行缓存this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}// Create proxy if we have advice.// 获取当前bean的Advices和AdvisorsObject[] specificInterceptors getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);// 对当前bean的代理状态进行缓存if (specificInterceptors ! DO_NOT_PROXY) {// 对当前bean的代理状态进行缓存this.advisedBeans.put(cacheKey, Boolean.TRUE);// 根据获取到的Advices和Advisors为当前bean生成代理对象Object proxy createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));// 缓存生成的代理bean的类型并且返回生成的代理beanthis.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;} 然后我们跳过logUtil看一下真正需要被创建代理对象的 myCalculator。 他会进入到 getAdvicesAndAdvisorsForBean方法中这个方法就是给当前的bean寻找适配的advisor对象我们知道advisor对象中包含advice对象advice对象中包含MethodLocadingFactory还有AspectJExpressionPointcut和SimpleBeanFactoryAwareAspectInstanceFactory对象。 思考一个问题我们根据什么条件给bean对象创建代理对象肯定是根据我们配置express表达式来判断哪些包那些类那些对象需要创建代理对象而Spring的匹配规则主要是通过ClassFilter和MethodMatcher对象来实现的之前我们只知道advice对象需要一个AspectJExpressionPointCut对象我们来看下这个类的继承关系图。 FunctionalInterface
public interface ClassFilter {/*** 是否应该将pointcut应用到给定的接口或者类上** Should the pointcut apply to the given interface or target class?* param clazz the candidate target class* return whether the advice should apply to the given target class*/boolean matches(Class? clazz);/*** ClassFilter的规范实例能够匹配所有的类** Canonical instance of a ClassFilter that matches all classes.*/ClassFilter TRUE TrueClassFilter.INSTANCE;}
/*** 一个特殊类型的MethodMatcher接口当匹配方法的时候需要将说明考虑进去** A specialized type of {link MethodMatcher} that takes into account introductions* when matching methods. If there are no introductions on the target class,* a method matcher may be able to optimize matching more effectively for example.** author Adrian Colyer* since 2.0*/
public interface IntroductionAwareMethodMatcher extends MethodMatcher {/*** Perform static checking whether the given method matches. This may be invoked* instead of the 2-arg {link #matches(java.lang.reflect.Method, Class)} method* if the caller supports the extended IntroductionAwareMethodMatcher interface.* param method the candidate method* param targetClass the target class* param hasIntroductions {code true} if the object on whose behalf we are* asking is the subject on one or more introductions; {code false} otherwise* return whether or not this method matches statically*/boolean matches(Method method, Class? targetClass, boolean hasIntroductions);}有了以上知识我们继续往下跟getAdvicesAndAdvisorsForBean方法。 /*** 检查前面切面解析是否有通知器advisors创建有就返回没有就是null* param beanClass the class of the bean to advise* param beanName the name of the bean* param targetSource* return*/OverrideNullableprotected Object[] getAdvicesAndAdvisorsForBean(Class? beanClass, String beanName, Nullable TargetSource targetSource) {// 找合适的增强器对象ListAdvisor advisors findEligibleAdvisors(beanClass, beanName);// 若为空表示没找到if (advisors.isEmpty()) {return DO_NOT_PROXY;}return advisors.toArray();} 里面是通过findEligibleAdvisors查找合适的advisor对象。 /*** 找到所有符合条件的通知对于自动代理的类** Find all eligible Advisors for auto-proxying this class.* param beanClass the clazz to find advisors for* param beanName the name of the currently proxied bean* return the empty List, not {code null},* if there are no pointcuts or interceptors* see #findCandidateAdvisors* see #sortAdvisors* see #extendAdvisors*/protected ListAdvisor findEligibleAdvisors(Class? beanClass, String beanName) {// 将当前系统中所有的切面类的切面逻辑进行封装从而得到目标AdvisorListAdvisor candidateAdvisors findCandidateAdvisors();// 对获取到的所有Advisor进行判断看其切面定义是否可以应用到当前bean从而得到最终需要应用的AdvisorListAdvisor eligibleAdvisors findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);// 提供的hook方法用于对目标Advisor进行扩展extendAdvisors(eligibleAdvisors);if (!eligibleAdvisors.isEmpty()) {// 对需要代理的Advisor按照一定的规则进行排序eligibleAdvisors sortAdvisors(eligibleAdvisors);}return eligibleAdvisors;} findCandidateAdvisors我们在之前就比较熟悉了他是寻找容器中所有的advisor对象他在之前第一次调用的时候就会初始化所有的advisor对象并且把他放入到缓存中去。 获取得到所有的advisor对象之后就会通过findAdvisorsThatCanApply查找可以应用在当前类的advisor对象如果找不到适配的advisor对象说明当前对象不需要被代理直接返回空表示不需要被代理我们继续往下看他的匹配过程。 /*** 检测实例化之后的bean是否需要通知器其实就是检测方法或者类上是否需要事务注解** Search the given candidate Advisors to find all Advisors that* can apply to the specified bean.* param candidateAdvisors the candidate Advisors* param beanClass the targets bean class* param beanName the targets bean name* return the List of applicable Advisors* see ProxyCreationContext#getCurrentProxiedBeanName()*/protected ListAdvisor findAdvisorsThatCanApply(ListAdvisor candidateAdvisors, Class? beanClass, String beanName) {ProxyCreationContext.setCurrentProxiedBeanName(beanName);try {// 从候选的通知器中找到合适正在创建的实例对象的通知器return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);}finally {ProxyCreationContext.setCurrentProxiedBeanName(null);}} 继续往下跟findAdvisorsThatCanApply方法。 /*** 遍历每一个advisor然后判断是否可以应用到目标类clazz上可以的话就加入候选列表** Determine the sublist of the {code candidateAdvisors} list* that is applicable to the given class.* param candidateAdvisors the Advisors to evaluate* param clazz the target class* return sublist of Advisors that can apply to an object of the given class* (may be the incoming List as-is)*/public static ListAdvisor findAdvisorsThatCanApply(ListAdvisor candidateAdvisors, Class? clazz) {// 若候选的增强器集合为空 直接返回if (candidateAdvisors.isEmpty()) {return candidateAdvisors;}// 定义一个合适的增强器集合对象ListAdvisor eligibleAdvisors new ArrayList();// 循环我们候选的增强器对象IntroductionAdvisor与PointcutAdvisor本质区别一个是可以作用在类上一个是可以作用的方法上for (Advisor candidate : candidateAdvisors) {// 判断我们的增强器对象是不是实现了IntroductionAdvisor (很明显我们事务的没有实现 所以不会走下面的逻辑)if (candidate instanceof IntroductionAdvisor canApply(candidate, clazz)) {eligibleAdvisors.add(candidate);}}// 是否有引介增强boolean hasIntroductions !eligibleAdvisors.isEmpty();for (Advisor candidate : candidateAdvisors) {// 判断我们的增强器对象是不是实现了IntroductionAdvisorif (candidate instanceof IntroductionAdvisor) {// already processed// 在上面已经处理过,不需要处理continue;}// 真正的判断增强器是否合适当前类型if (canApply(candidate, clazz, hasIntroductions)) {eligibleAdvisors.add(candidate);}}return eligibleAdvisors;} 第一个循环我们所有获取得到的advisor对象判断当前的advisor对象是否是引介增强之前我们都知道我们AOP创建的advisor都是AspectJPointcutAdvisor对象所以我们跳过直接看canApply方法。
public static boolean canApply(Advisor advisor, Class? targetClass, boolean hasIntroductions) {// 如果是IntroductionAdvisor的话则调用IntroductionAdvisor类型的实例进行类的过滤// 这里是直接调用的ClassFilter的matches方法if (advisor instanceof IntroductionAdvisor) {return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);}// 通常我们的Advisor都是PointcutAdvisor类型else if (advisor instanceof PointcutAdvisor) {// 转为PointcutAdvisor类型PointcutAdvisor pca (PointcutAdvisor) advisor;//这里从Advisor中获取Pointcut的实现类 这里是AspectJExpressionPointcutreturn canApply(pca.getPointcut(), targetClass, hasIntroductions);}else {// It doesnt have a pointcut so we assume it applies.return true;}} 这里开始也是有一个advisor对象的类型判断我们继续往下跟他具体实现的canApply方法。
public static boolean canApply(Pointcut pc, Class? targetClass, boolean hasIntroductions) {Assert.notNull(pc, Pointcut must not be null);// 进行切点表达式的匹配最重要的就是ClassFilter和MethodMatcher这两个方法的实现。// MethodMatcher中有两个matches方法。一个参数是只有Method对象和targetClass另一个参数有// Method对象和targetClass对象还有一个Method的方法参数,他们两个的区别是// 两个参数的matches是用于静态的方法匹配 三个参数的matches是在运行期动态的进行方法匹配的// 先进行ClassFilter的matches方法校验// 首先这个类要在所匹配的规则下if (!pc.getClassFilter().matches(targetClass)) {return false;}// 再进行MethodMatcher方法级别的校验MethodMatcher methodMatcher pc.getMethodMatcher();if (methodMatcher MethodMatcher.TRUE) {// No need to iterate the methods if were matching any method anyway...return true;}// 判断匹配器是不是IntroductionAwareMethodMatcherIntroductionAwareMethodMatcher introductionAwareMethodMatcher null;if (methodMatcher instanceof IntroductionAwareMethodMatcher) {introductionAwareMethodMatcher (IntroductionAwareMethodMatcher) methodMatcher;}// 创建一个集合用于保存targetClass的class对象SetClass? classes new LinkedHashSet();// 判断当前class是不是代理的class对象if (!Proxy.isProxyClass(targetClass)) {// 加入到集合中去classes.add(ClassUtils.getUserClass(targetClass));}// 获取到targetClass所实现的接口的class对象然后加入到集合中classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));// 循环所有的class对象for (Class? clazz : classes) {// 通过class获取到所有的方法Method[] methods ReflectionUtils.getAllDeclaredMethods(clazz);// 循环我们的方法for (Method method : methods) {// 只要有一个方法能匹配到就返回true// 这里就会有一个问题因为在一个目标中可能会有多个方法存在有的方法是满足这个切点的匹配规则的// 但是也可能有一些方法是不匹配切点规则的这里检测的是只有一个Method满足切点规则就返回true了// 所以在运行时进行方法拦截的时候还会有一次运行时的方法切点规则匹配if (introductionAwareMethodMatcher ! null ?introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :// 通过方法匹配器进行匹配methodMatcher.matches(method, targetClass)) {return true;}}}return false;} 这里就比较有意思了首先获取对应的classFilter进行类级别的匹配然后会在循环方法进行方法级别的匹配。 这里看得到匹配到一个方法就返回true因为这里只是单纯的判断当前类是否需要创建代理对对象在后续的创建代理对象的时候会再具体进行匹配所以这里匹配到一个就直接返回true。 进过以上一系列判断我们就可以获取得到当前bean适配的所有的advisor对象。 获取得到对应的所有的advisor对象的时候对调用一个对这些advisor进行拓extendAdvisors我们继续往下跟。 Overrideprotected void extendAdvisors(ListAdvisor candidateAdvisors) {AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);}public static boolean makeAdvisorChainAspectJCapableIfNecessary(ListAdvisor advisors) {// Dont add advisors to an empty list; may indicate that proxying is just not requiredif (!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;} 可以看得到他只是给我们的advisor集合中添加了ExposeInvocationInterceptor,这个类的作用是啥呢在解决这个问题之前首先问一下大家我们生成的这个advisor对象在执行切面逻辑的时候是不是会有执行顺序答案是肯定会有的那我们如果控制这些advisor的执行顺序呢 我们看下ExposeInvocationIntercetor里面有啥。 其实他就是通过这个ExposeInvocationInterceptor里面维护的一个ThreadLocal来控制当前的执行的advisor对象 。 public static final Advisor ADVISOR new DefaultPointcutAdvisor(INSTANCE) {Overridepublic String toString() {return ExposeInvocationInterceptor.class.getName() .ADVISOR;}};private static final ThreadLocalMethodInvocation invocation new NamedThreadLocal(Current AOP method invocation);/*** 此处是继续调用ReflectiveMethodInvocation的proceed方法来进行递归调用** Return the AOP Alliance MethodInvocation object associated with the current invocation.* return the invocation object associated with the current invocation* throws IllegalStateException if there is no AOP invocation in progress,* or if the ExposeInvocationInterceptor was not added to this interceptor chain*/public static MethodInvocation currentInvocation() throws IllegalStateException {MethodInvocation mi invocation.get();if (mi null) {throw new IllegalStateException(No MethodInvocation found: Check that an AOP invocation is in progress and that the ExposeInvocationInterceptor is upfront in the interceptor chain. Specifically, note that advices with order HIGHEST_PRECEDENCE will execute before ExposeInvocationInterceptor! In addition, ExposeInvocationInterceptor and ExposeInvocationInterceptor.currentInvocation() must be invoked from the same thread.);}return mi;} 既然我们的advisor有执行顺序所以spring接下来就是对获取得到的advisor对象进行排序。 protected ListAdvisor findEligibleAdvisors(Class? beanClass, String beanName) {// 将当前系统中所有的切面类的切面逻辑进行封装从而得到目标AdvisorListAdvisor candidateAdvisors findCandidateAdvisors();// 对获取到的所有Advisor进行判断看其切面定义是否可以应用到当前bean从而得到最终需要应用的AdvisorListAdvisor eligibleAdvisors findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);// 提供的hook方法用于对目标Advisor进行扩展extendAdvisors(eligibleAdvisors);if (!eligibleAdvisors.isEmpty()) {// 对需要代理的Advisor按照一定的规则进行排序eligibleAdvisors sortAdvisors(eligibleAdvisors);}return eligibleAdvisors;} 这里的排序就比较麻烦了他使用到的是一个拓扑有限无环排序有兴趣的伙伴可以去研究一下这个算法。 最后就会返回排好序的advisor对象接下来就是真正创建代理对象。在看创建代理对象的之前如果对cglib跟jdk动态代理源码不是很熟悉的先去看一下之前的博客Spring源码解析(24)之JDK动态代理与cglib动态代理源码解析_spring 选择 jdk 代理 cglib 代理源码-CSDN博客 接下来会先画一个图总结一下这三篇博客的脉络然后再往下看他是如何创建代理对象的。