一、BeanDefinition
1.1、概述
BeanDefinition是一个接口,主要负责存储bean的定义信息,决定bean的生产方式,是一个定义态的bean,类似于说明书。后续BeanFactory就可以根据这些信息生产bean了。比如实例化:可以通过反射得到实例对象;比如:lazy,则不会在IOC加载的时候创建bean;
二、加载过程
说明:以下代码是基于JavaConfig的方式。
2.1、过程概览
BeanDefinition的加载链路非常长,很容易就把人绕晕了,需要耐心阅读,但是大的流程是不变的,即:启动IOC容器===>解析配置类===>注册为BeanDefinitionMap。
2.1.1、启动IOC容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MySpringConfig.class);
2.1.2、解析配置类
# 第一步
# 第二步
# 第三步
# 第四步
# 第五步
# 第六步
2.1.3、注册为beanDefinitionMap
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException {Assert.hasText(beanName, "Bean name must not be empty");Assert.notNull(beanDefinition, "BeanDefinition must not be null");if (beanDefinition instanceof AbstractBeanDefinition) {try {((AbstractBeanDefinition) beanDefinition).validate();} catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,"Validation of bean definition failed", ex);}}BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);if (existingDefinition != null) {if (!isAllowBeanDefinitionOverriding()) {throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);}else if (existingDefinition.getRole() < beanDefinition.getRole()) {// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTUREif (logger.isInfoEnabled()) {logger.info("Overriding user-defined bean definition for bean '" + beanName +"' with a framework-generated bean definition: replacing [" +existingDefinition + "] with [" + beanDefinition + "]");}}else if (!beanDefinition.equals(existingDefinition)) {if (logger.isDebugEnabled()) {logger.debug("Overriding bean definition for bean '" + beanName +"' with a different definition: replacing [" + existingDefinition +"] with [" + beanDefinition + "]");}}else {if (logger.isTraceEnabled()) {logger.trace("Overriding bean definition for bean '" + beanName +"' with an equivalent definition: replacing [" + existingDefinition +"] with [" + beanDefinition + "]");}}this.beanDefinitionMap.put(beanName, beanDefinition);}else {if (hasBeanCreationStarted()) {// Cannot modify startup-time collection elements anymore (for stable iteration)synchronized (this.beanDefinitionMap) {this.beanDefinitionMap.put(beanName, beanDefinition);List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);updatedDefinitions.addAll(this.beanDefinitionNames);updatedDefinitions.add(beanName);this.beanDefinitionNames = updatedDefinitions;removeManualSingletonName(beanName);}}else {// Still in startup registration phasethis.beanDefinitionMap.put(beanName, beanDefinition);this.beanDefinitionNames.add(beanName);removeManualSingletonName(beanName);}this.frozenBeanDefinitionNames = null;}if (existingDefinition != null || containsSingleton(beanName)) {resetBeanDefinition(beanName);}
}
2.2、类比小汽车的制造过程
2.3、小总结
BeanDefinition用来描述bean的定义信息,决定着bean如何生产,是一个定义态的bean。我们在创建Spring容器的时候,首先会去读取配置,然后解析配置,将符合条件的bean注册为beanDefinitionMap,然后工厂根据这些描述信息去生产bean,可以类比小汽车的制造过程。