关键词:
Bean创建入口:finishBeanFactoryInitialization(beanFactory);
转化服务:ConversionService
值解析器:propertySourcePlaceholderConfigurer
合并Bean的定义信息:getMergedLocalBeanDefinition
工厂Bean:FactoryBean
一:Bean的创建入口
解释:从AbstractApplicationContext下的refresh方法下的finishBeanFactoryInitialization(beanFactory)进入。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 为上下文初始化类型转换器
// 1.判断IOC容器中是否存在了conversionService这个BeanName==>也就是我们在Application中进行注册的那个Bean
// 2.如果存在这个Bean的话,就将转化服务注册到IOC容器中
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// 如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器,主要用于注解属性值的解析
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// 尽早初始化loadTimeWeaverAware bean,以便尽早注册它们的转换器
// 【何时注入】在prepareBeanFactory(beanFactory);时注入了LoadTimeWeaverAware
// AOP时再讲
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
// 禁止使用临时类加载器进行类型匹配
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
// 冻结所有的bean定义,说明注册的bean定义将不被修改或任何进一步的处理
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 实例化剩下的单例对象
beanFactory.preInstantiateSingletons();
}
二:转化服务
1.从源码中可知,如果容器中存在ConversionService这个BeanName的话,就将它注册到IOC容器中
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
2.怎么理解转换服务?
2.1就像之前提到的属性解析器一样,我们可以输入一个字符串"province_city_country",以下划线的方式分隔成独立字段然后注入到Address类的属性中
3.怎么使用转换服务?
3.1自定义的转化服务可以必须选择继承3个父接口,分别是:Converter,GenericeConverter,ConverterFactory
3.2在xml配置文件中,注入到ConversionServiceFactoryBean的converters集合内
3.3关于三个父接口的差别与xml文件中的配置见下图
三: 值解析器:propertySourcePlaceholderConfigurer
1.什么作用,类似于可以对"${","}"进行解析
2.什么时候注入
2.1xml文件中
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
3.什么时候内置到IOC容器中的,见下图可知
该类是BFPP类型,所以当IOC容器中识别到该类时,会调用一些列的方法,并调用postProcessorBeanFactory方法,之后就进行了一些列的调用
四:合并Bean的定义信息:getMergedLocalBeanDefinition
1.合并的对象是什么?是当前对象和其以上父类的信息合并。
2.为什么合并?
2.1子类继承父类,也继承了父类的公有属性
2.2当我们获取到Bean的初始化BeanDefinition时,并未进行创建,所以父类也没有加载
2.3当我们获取到父类的BeanDefinition并将其丰富自身的BeanDefinition。这样后续在创建Bean的时候,就可以直接那合并后的BeanDefinition直接进行创建。
2.4什么时候进行合并的?
==>在进行调用BFPP时,我们使用到了getBeanNamesForType(),在该方法的调用链下我们第一次使用到了getMergedLocalBeanDefinition。
==>在这里我们只对getMergedLocalBeanDefinition进行阐述,见下图
五:工厂Bean:FactoryBean
1.怎么理解BeanFactory于FactoryBean
2.为什么getBean('&FactoryBean的beanName')和
getBean('FactoryBean的beanName')得到的对象不一样?Spring是怎么区分的仅仅是通过一个'&'
3.见下图