前面文章:注解何时解析,提到了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交给容器管理。