Bean注解原理分析

前面文章:注解何时解析,提到了Bean注解何时被解析。

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>();
		ConfigurationClassParser parser = new ConfigurationClassParser(
				this.metadataReaderFactory, this.problemReporter, this.environment,
				this.resourceLoader, this.componentScanBeanNameGenerator, registry);

		do {
			//解析配置。@import,@compengScan等注解都在这里面实现。前面讲到的方法
			parser.parse(candidates);
			parser.validate();
			
			if (this.reader == null) {
				this.reader = new ConfigurationClassBeanDefinitionReader(
						registry, this.sourceExtractor, this.resourceLoader, this.environment,
						this.importBeanNameGenerator, parser.getImportRegistry());
			}
			//对@bean解析的添加到beanDefinition(处理bean注解)
			this.reader.loadBeanDefinitions(configClasses);
	}
	
	//configurationModel添加了bean注解的类,在前面parse添加的
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
		TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
		for (ConfigurationClass configClass : configurationModel) {
			loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
		}
	}
	
	//处理类中的bean注解方法
private void loadBeanDefinitionsForConfigurationClass(
			ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {	
		//将@bean注解的bean添加到BeanDefinitionMap中
		for (BeanMethod beanMethod : configClass.getBeanMethods()) {
			loadBeanDefinitionsForBeanMethod(beanMethod);
		}

	}
	//处理bean注解方法
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
		ConfigurationClass configClass = beanMethod.getConfigurationClass();
		MethodMetadata metadata = beanMethod.getMetadata();
		String methodName = metadata.getMethodName();
		if (metadata.isStatic()) {
			// static @Bean method
			beanDef.setBeanClassName(configClass.getMetadata().getClassName());
			beanDef.setFactoryMethodName(methodName);
		}
		else {
			//这里会给BeanDefinition设置factoryBeanName属性
			beanDef.setFactoryBeanName(configClass.getBeanName());
			//设置了factoryMethodName属性,后面实例化要用到
			beanDef.setUniqueFactoryMethodName(methodName);
		}
		//添加到beanDefinitionMap中
		this.registry.registerBeanDefinition(beanName, beanDefToRegister);
	}
  • 上面就是解析类中bean注解的方法,并给BeanDefinition设置了factoryBeanName属性。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
		
      //这里判断BeanDefinition有没有设置factoryBeanName属性,前面设置了
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// 实例化bean
		return instantiateBean(beanName, mbd);
	}
	//instantiateUsingFactoryMethod()这里面会调用我们bean注解的方法,并拿到返回值。
protected BeanWrapper instantiateUsingFactoryMethod(
			String beanName, RootBeanDefinition mbd, Object[] explicitArgs) {

		return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
	}
  • 会从beanDefinitionMap中取出,并实例化,如果设置factoryBeanName属性,就反射调用Bean注解方法,并拿到返回值bean。

总结:解析类中方法是否含有bean注解,如果含有就会给BeanDefinition设置factoryBeanName属性,有这个属性实例化的时候会利用方法反射调用自己的Bean注解方法,拿到返回值bean,把bean交给容器管理。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值