SpringBean注册之@Configuration配置类解析过程

前言

使用@Configuration注解标注配置类,大家已经驾轻就熟了,但spring对Configuration配置类的解析是怎样的,其中又涉及哪些关键点和值得探究的地方,下面主要对这些疑点进行分析;
首先分析下ConfigurationClassPostProcessor,该类主要完成@Configuration类的处理

一、ConfigurationClassPostProcessor的注册时机

SpringIOC - BeanFactory浅析一文中可以知道ConfigurationClassPostProcessor注册时机是初始化容器过程中,代码如下

public AnnotationConfigApplicationContext() {
        //对DefaultListableBeanFactory进行初始化
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
}

new AnnotatedBeanDefinitionReader(this)底层使用了registerAnnotationConfigProcessors方法

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) {
        //获取对象
		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
	    //忽略代码.........
		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
		
		/**********************************检查有没有,如果没有注册*************************/
		
         //org.springframework.context.annotation.internalConfigurationAnnotationProcessor。
         //@Configuration注解处理器
         //ConfigurationClassPostProcessor是一个BeanFactoryPostProcessor(BeanDefinitionRegistryPostProcessor)
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}
       //忽略代码.........

容器在初始化时,会收集ConfigurationClassPostProcessor信息,把他封装成BeanDefinition对象注册到BeanFactory的BeanDefinition池中

二、ConfigurationClassPostProcessor的调用时机

在这里插入图片描述
从上图可以看出ConfigurationClassPostProcessor是一个BeanFactoryPostProcessorBeanDefinitionRegistry,所以这个类会在refresh方法中invokeBeanFactoryPostProcessors(beanFactory)执行,其底层如下

public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		//只有此beanFactory 是BeanDefinitionRegistry  才能执行BeanDefinitionRegistryPostProcessor,才能修改Bean的定义嘛~
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

			 //忽略代码。。。。。。。。

			// 先执行实现了PriorityOrdered接口的,然后是Ordered接口的,最后执行剩下的
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
			// 先从容器中拿出来所有的BeanDefinitionRegistryPostProcessor的名字 
			// 本例中有一个这个类型的处理器:ConfigurationClassPostProcessor(显然是处理@Configuration这种Bean的)
			String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					// 实例化取到的BeanDefinitionRegistryPostProcessor,并且把他放到单利池中
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			// 排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			// 此处缓冲起来(需要注意的是,是排序后,再放进去的 这样是最好的)
			registryProcessors.addAll(currentRegistryProcessors);
			// 这个方法很简单,就是吧currentRegistryProcessors里面所有的处理器for循环一个个的执行掉
			//所以这里会执行ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			// 此处把当前持有的执行对象给清空了,需要注意。以方便装载后续执行的处理器们
			currentRegistryProcessors.clear();

          //执行Ordered的BeanDefinitionRegistryPostProcessor,不包括我们在上面执行的。。。。。。。。

         //执行剩下的BeanDefinitionRegistryPostProcessor。。。。。。。。

        //执行BeanFactoryPostProcessor的方法postProcessBeanFactory
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);

       //忽略代码。。。。。
	}

从上面代码可以看出,Spring是先执行ConfigurationClassPostProcessor重写BeanDefinitionRegistry的方法,在执行其重写BeanFactoryPostProcessor的方法。

三、注册我们自己注入bean的BeanDefinition

其发生在ConfigurationClassPostProcessor重写BeanDefinitionRegistry的postProcessBeanDefinitionRegistry方法

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
	    //忽略代码..........
		processConfigBeanDefinitions(registry);
	}
//@Configuration类的注册并验证配置模型
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
        //
		List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
		//获取所有已经注册的BeanDefinition,注意,这时我们自己的bean的BeanDefinition还没有注册
		String[] candidateNames = registry.getBeanDefinitionNames();
		for (String beanName : candidateNames) {
			BeanDefinition beanDef = registry.getBeanDefinition(beanName);
			//如果配置已经解析过了
			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
				if (logger.isDebugEnabled()) {
					logger.debug("");
				}
			}
			//判断这些BeanDefinition所描述的类上是否有@Configuration,注解,如果有就把这个类设置成full模式
			//判断这些BeanDefinition所描述的类上是否有@Bean,@Component,@ComponentScan,@Import,@ImportResource,注解,
			//如果有就把这个类设置成lite模式,
			else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
				configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
			}
		}
		// 如果找不到@Configuration类,则立即返回
		if (configCandidates.isEmpty()) {
			return;
		}

		// 按先前确定的@订单值排序(如果适用)
		configCandidates.sort((bd1, bd2) -> {
			int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
			int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
			return Integer.compare(i1, i2);
		});

		// 检测通过封闭应用程序上下文提供的任何自定义bean名称生成策略
		SingletonBeanRegistry sbr = null;
		if (registry instanceof SingletonBeanRegistry) {
			sbr = (SingletonBeanRegistry) registry;
			if (!this.localBeanNameGeneratorSet) {
				BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
				if (generator != null) {
					this.componentScanBeanNameGenerator = generator;
					this.importBeanNameGenerator = generator;
				}
			}
		}

		if (this.environment == null) {
			this.environment = new StandardEnvironment();
		}

		// 生成解析@Configuration的类ConfigurationClassParser
		//他在初始化时会实例化ConditionEvaluator类,它是解析@Conditional注解
	    //他在初始化时会实例化ComponentScanAnnotationParser类,它是解析@ComponentScan注解
		ConfigurationClassParser parser = new ConfigurationClassParser(
				this.metadataReaderFactory, this.problemReporter, this.environment,
				this.resourceLoader, this.componentScanBeanNameGenerator, registry);
        //包查询到到配置类放到这里来
		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
		//这里是放置已经解析好的配置类
		Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
		do {
		   //解析配置类,把我们配置到bean封装成BeanDefinition,放到BeanDefinition池中
			parser.parse(candidates);
			//验证 如果是配置类,那么不能是final,因为他要进行继承代理
			//@Bean标注的方法不能是private final的,
			//注意方法可以是static的,虽然static方法不能被重写,但是他可以被继承
			//尽量不要是static方法,因为CGLIB代理不能重写static方法。
			parser.validate();
            //获取通过配置类解析得到的类信息,包括配置类
			Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
			//这段代码根据没有意义,因为alreadyParsed是空的,他还没有被赋值
			configClasses.removeAll(alreadyParsed);

			// 阅读模型并基于其内容创建bean定义
			if (this.reader == null) {
				this.reader = new ConfigurationClassBeanDefinitionReader(
						registry, this.sourceExtractor, this.resourceLoader, this.environment,
						this.importBeanNameGenerator, parser.getImportRegistry());
			}
			this.reader.loadBeanDefinitions(configClasses);
			alreadyParsed.addAll(configClasses);

			candidates.clear();
			if (registry.getBeanDefinitionCount() > candidateNames.length) {
				String[] newCandidateNames = registry.getBeanDefinitionNames();
				Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
				Set<String> alreadyParsedClasses = new HashSet<>();
				for (ConfigurationClass configurationClass : alreadyParsed) {
					alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
				}
				for (String candidateName : newCandidateNames) {
					if (!oldCandidateNames.contains(candidateName)) {
						BeanDefinition bd = registry.getBeanDefinition(candidateName);
						if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
								!alreadyParsedClasses.contains(bd.getBeanClassName())) {
							candidates.add(new BeanDefinitionHolder(bd, candidateName));
						}
					}
				}
				candidateNames = newCandidateNames;
			}
		}
		while (!candidates.isEmpty());

		// 将ImportRegistry注册为bean以支持ImportAware@Configuration类
		if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
			sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
		}

		if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
			//清除外部提供的MetadataReaderFactory中的缓存;这是一个no操作
            //对于共享缓存,因为它将被ApplicationContext清除。
			((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
		}
	}

1、执行ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法
2、获取当前spring中所有注册的BeanDefinition,注意这时候我们自己的bean的BeanDefinition还没有注册
3、判断这些BeanDefinition所描述的类上是否有@Configuration@Bean@Component@ComponentScan@Import@ImportResource注解,如果有就把他放到configCandidates集合中。

注意:一般情况下,这时候容器存在我们自己定义的类只有配置类。因为我们使用了register方法把配置类事先注册到spring容器中去了。
代码如下

AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(RootConfig.class);
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		//生产bean工厂
		this();
		//将配置类注入bean工厂
		register(annotatedClasses);

		refresh();
	}

配置类可以理解是我们手动注册进去的。
4、生成ConfigurationClassParser解析类,调用其parse方法解析这些配置类。

1、parser.parse(candidates);

public void parse(Set<BeanDefinitionHolder> configCandidates) {
		for (BeanDefinitionHolder holder : configCandidates) {
			BeanDefinition bd = holder.getBeanDefinition();
			try {
			    //配置类在注册时都是以AnnotatedBeanDefinition类注册的,所以配置类进入这里
				if (bd instanceof AnnotatedBeanDefinition) {
				    //其底层是processConfigurationClass方法
					parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
				}
				else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
					parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
				}
				else {
					parse(bd.getBeanClassName(), holder.getBeanName());
				}
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Throwable ex) {
				throw new BeanDefinitionStoreException(
						"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
			}
		}
         //处理DeferredImportSelector类型的实现类
		this.deferredImportSelectorHandler.process();
	}

protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
		//根据{@code@Conditional}批注确定是否应跳过项。
		if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
			return;
		}

		ConfigurationClass existingClass = this.configurationClasses.get(configClass);
		//忽略代码。。。。。。。。

		// 把ConfigurationClass类型转换成SourceClass类型
		SourceClass sourceClass = asSourceClass(configClass);
		do {
			sourceClass = doProcessConfigurationClass(configClass, sourceClass);
		}
		while (sourceClass != null);

		this.configurationClasses.put(configClass, configClass);
	}
@Nullable
	protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
			throws IOException {

        //处理@Component注解
		if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
			//递归地首先处理任何成员(嵌套)类
			processMemberClasses(configClass, sourceClass);
		}

		// 处理@PropertySource注解
		for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), PropertySources.class,
				org.springframework.context.annotation.PropertySource.class)) {
			if (this.environment instanceof ConfigurableEnvironment) {
				processPropertySource(propertySource);
			}
			else {
				logger.info("");
			}
		}

		// 处理@ComponentScan注解
		Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
		if (!componentScans.isEmpty() &&
				!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
			for (AnnotationAttributes componentScan : componentScans) {
				// The config class is annotated with @ComponentScan -> perform the scan immediately
				Set<BeanDefinitionHolder> scannedBeanDefinitions =
						this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
				// Check the set of scanned definitions for any further config classes and parse recursively if needed
				for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
					BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
					if (bdCand == null) {
						bdCand = holder.getBeanDefinition();
					}
					if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
						parse(bdCand.getBeanClassName(), holder.getBeanName());
					}
				}
			}
		}

		// 处理任何@Import注释
		processImports(configClass, sourceClass, getImports(sourceClass), true);

		// 处理任何@ImportResource注释
		AnnotationAttributes importResource =
				AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
		if (importResource != null) {
			String[] resources = importResource.getStringArray("locations");
			Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
			for (String resource : resources) {
				String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
				configClass.addImportedResource(resolvedResource, readerClass);
			}
		}

		// 处理单个@Bean方法
		Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
		for (MethodMetadata methodMetadata : beanMethods) {
			configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
		}

		// 处理接口上的默认方法
		processInterfaces(configClass, sourceClass);

		// 进程超类(如果有)
		if (sourceClass.getMetadata().hasSuperClass()) {
			String superclass = sourceClass.getMetadata().getSuperClassName();
			if (superclass != null && !superclass.startsWith("java") &&
					!this.knownSuperclasses.containsKey(superclass)) {
				this.knownSuperclasses.put(superclass, configClass);
				// 找到超类,返回其注释元数据并递归
				return sourceClass.getSuperClass();
			}
		}
		// 没有超类->处理完成
		return null;
	}

为配置类进行Cglib代理

下面我们来看看ConfigurationClassPostProcessorpostProcessBeanFactory方法

通过用CGLIB增强的子类替换bean请求,准备在运行时为其提供服务的配置类

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	    //忽略代码。。。。。。
	    //生成配置类的代理类
		enhanceConfigurationClasses(beanFactory);
		beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
	}
//生成配置类的代理类
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
		Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
		//循环所有的BeanDefinition
		for (String beanName : beanFactory.getBeanDefinitionNames()) {
			BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);//判断其是否是全注解类,有@Configuration注解的就是全注解类
			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
				if (!(beanDef instanceof AbstractBeanDefinition)) {
					throw new BeanDefinitionStoreException("");
				}
				else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) {
					logger.info("");
				}
				//如果是全注解类就放到集合configBeanDefs中
				configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
			}
		}
		//没有找到配置类,直接返回
		if (configBeanDefs.isEmpty()) {
			return;
		}
        //代理类生成器
		ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
		//循环配置类
		for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
		   //获取配置类 
			AbstractBeanDefinition beanDef = entry.getValue();
			//如果@Configuration类被代理,则始终代理目标类
			beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
			try {
				//获取当前配置类的class
				Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
				if (configClass != null) {
				    //获取当前配置类class的代理class对象
					Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
					if (configClass != enhancedClass) {
						if (logger.isTraceEnabled()) {
							logger.trace("");
						}
						//重新设置配置类的BeanDefinition的中的class信息,赋值为代理类的class
						beanDef.setBeanClass(enhancedClass);
					}
				}
			}
			catch (Throwable ex) {
				throw new IllegalStateException("");
			}
		}
	}

其中最重要的是这个方法

//利用代理器生成代理类
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);

其原理如下:

class ConfigurationClassEnhancer {
    //对方法的增强策略
	private static final Callback[] CALLBACKS = new Callback[] {
	        //拦截对任何{@link Bean}注释方法的调用,以确保正确处理Bean语义,如作用域和AOP代理
			new BeanMethodInterceptor(),
			//设置一个BeanFactory
			new BeanFactoryAwareMethodInterceptor(),
			NoOp.INSTANCE
	};
public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
         //如果配置类已经进行代理了(因为代理类都实现这个类)
		if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
			if (logger.isDebugEnabled()) {logger.debug(String.format(""));}
			return configClass;
		}
		//如果不是代理类,生成代理类
		Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
		return enhancedClass;
	}

	
	private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(configSuperClass);//代理类继承目标类
		enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});//代理类实现EnhancedConfiguration接口
		enhancer.setUseFactory(false);
		enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
		//BeanFactoryAwareGeneratorStrategy作用是为代理类生成一个BeanFactory的public属性
		enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
		enhancer.setCallbackFilter(CALLBACK_FILTER);
		enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
		return enhancer;
	}

假如我们的配置类名是RootCongfig,那么配置类的代理类就是这样

public CglibLRootCongfig extends RootCongfig implements EnhancedConfiguration{
       
     public BeanFactory $$beanFactory

}

上面案例只能看出代理类与目标类的关系,还不能看出代理类对目标类方法的增强,代理类是使用BeanMethodInterceptor类对目标类进行增强,如下:

private static class BeanMethodInterceptor implements MethodInterceptor, ConditionalCallback { 
        //增强标注@Bean的方法以检查提供的BeanFactory
		public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,MethodProxy cglibMethodProxy) throws Throwable {
            //获取BeanFactory
			ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
			//获取当前@Bean标注方法生成bean的名字
			String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);
			// 确定此bean是否为作用域代理
			if (BeanAnnotationHelper.isScopedProxy(beanMethod)) {
				String scopedBeanName = ScopedProxyCreator.getTargetBeanName(beanName);
				if (beanFactory.isCurrentlyInCreation(scopedBeanName)) {
					beanName = scopedBeanName;
				}
			}
            //判断当前bean是否是factoryBean
			if (factoryContainsBean(beanFactory, BeanFactory.FACTORY_BEAN_PREFIX + beanName) &&
					factoryContainsBean(beanFactory, beanName)) {
				Object factoryBean = beanFactory.getBean(BeanFactory.FACTORY_BEAN_PREFIX + beanName);
				if (factoryBean instanceof ScopedProxyFactoryBean) {
					// 作用域代理工厂bean是一种特殊情况,不应进一步代理
				}
				else {
					// 它是一个候选工厂-继续改进
					return enhanceFactoryBean(factoryBean, beanMethod.getReturnType(), beanFactory, beanName);
				}
			}
           //检查给定的方法beanMethod是否是容器当前调用的工厂方法,判断依据是方法名和方法参数类型,个数是否相同
			if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
	             //如果是同一个方法就直接执行目标类的方法
				return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
			}
             //否则直接调用方法其返回值
			return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
		}

检查给定的方法beanMethod是否是容器当前调用的工厂方法,这个有的绕。

@ComponentScan(value = {"aop"})
@Configuration
public class RootConfig {
	@Bean
	public  Demo  demo(){
		return new Demo();
	}
	@Bean
	public  Father  father(){
		demo()
		return new Demo();
	}
}

Spring会把当前执行当方法放到当前线程的ThreadLocal中
当执行demo方法时,当前线程执行方法是demo。配置类会执行demo的增强方法,因为调用方法和执行方法是同一个方法,且其方法内部没有RootConfig配置类当其他方法,所以直接执行代理类的父类,就是原配置类的方法。

当执行father方法时,当前线程执行方法是father。配置类会执行father的增强方法,因为其底层有RootConfig配置类当其他增强方法demo,所以就会执行demo的增强方法,这个调用方法是demo,执行方法是father,他们不是同一个方法,所以Spring会直接返回demo的值,不会进行demo方法的调用。

发布了34 篇原创文章 · 获赞 0 · 访问量 1359

猜你喜欢

转载自blog.csdn.net/qq_41071876/article/details/105042890