spring
一、refresh
debug模式,跟踪 SpringApplication.run() 启动方法,进入SpringApplication类,发现调用其refresh方法,该方法调用AbstractApplicationContext类的 refresh()。
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { @Override public void refresh() throws BeansException, IllegalStateException {
// 给容器refresh加锁,避免容器处在refresh阶段,容器进行了初始化或销毁的操作 synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. // 准备刷新上下文。(为刷新准备此上下文,设置其启动日期和活动标志以及执行属性源的任何初始化。) prepareRefresh(); // Tell the subclass to refresh the internal bean factory. // 告诉子类刷新内部 bean 工厂。(之前的beanFactory如果存在的话则关闭,然后创建新的beanFactory
// 调用refreshBeanFactory():
// 1、创建了 DefaultListableBeanFactory 对象 -- 创建BeanFactory用来操作Bean:存储Bean的定义信息,实例化Bean、填充属性、初始化Bean、完整Bean、销毁Bean
// 2、customizeBeanFactory(beanFactory); -- 自定义BeanFactory
// 3、loadBeanDefinitions(beanFactory); -- 加载bean的定义信息
// 设置 Environment -- 环境变量和系统变量、ResourceLoader、BeanDefinitionReader -- 读取Bean定义信息、[BeanDefinitionRegistry、EntityResolver]等
// 4、synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory;}。
-- refreshBeanFactory()其后的getBeanFactory()会获取这个beanFactory。beanFactory是线程共享的,为了保证线程安全所以加上对象锁。
// 其声明:private final Object beanFactoryMonitor = new Object();
// ) ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. // 准备在此上下文中使用的 bean 工厂。(配置工厂的标准上下文特性,例如上下文的类加载器和后处理器) prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. // 允许在上下文子类中对 bean 工厂进行后处理。(扩展用的:其他框架或第三方插件重写使用) postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. // 调用在上下文中注册为 bean 的工厂处理器。(实例化并调用所有已注册的 BeanFactoryPostProcessor bean,如果给定顺序,按显式顺序。) invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. // 注册拦截 bean 创建的 bean 处理器。 registerBeanPostProcessors(beanFactory); // Initialize message source for this context. // 初始化此上下文的消息源。(国际化配置) initMessageSource(); // Initialize event multicaster for this context. // 为此上下文初始化事件多播器。 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // 初始化特定上下文子类中的其他特殊 bean。(扩展用的) onRefresh(); // Check for listener beans and register them. // 检查侦听器 bean 并注册它们。 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. // 实例化所有剩余的(非懒加载)单例。 finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. // 最后一步:发布对应的事件。 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. // 销毁已经创建的单例以避免悬空资源。 destroyBeans(); // Reset 'active' flag. // 重置“活动”标志。 cancelRefresh(ex); // Propagate exception to caller. // 将异常传播给调用者。 throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... // 重置 Spring 核心中的常见内省缓存,因为我们 // 可能不再需要单例 bean 的元数据... resetCommonCaches(); } } } }
参考:https://www.cnblogs.com/lemon-flm/p/7551744.html 多线程同步问题。
二、DefaultListableBeanFactor (转载:https://www.cnblogs.com/duanxz/p/5426638.html)
1. DefaultListableBeanFactory的作用
默认实现了ListableBeanFactory和BeanDefinitionRegistry接口,基于bean definition对象,是一个成熟的bean factroy。
最典型的应用是:在访问bean前,先注册所有的definition(可能从bean definition配置文件中)。使用预先建立的bean定义元数据对象,从本地的bean definition表中查询bean definition因而将不会花费太多成本。
DefaultListableBeanFactory既可以作为一个单独的beanFactory,也可以作为自定义beanFactory的父类。
注意:特定格式bean definition的解析器可以自己实现,也可以使用原有的解析器,如:
PropertiesBeanDefinitionReader和XmLBeanDefinitionReader。
2. DefaultListableBeanFactory的继承关系
以下出处:https://blog.csdn.net/Taylar_where/article/details/90547570
3.DeafultListableBeanFactory所实现的接口及接口作用:
AliasRegistry: AliasRegistry是制定别名的管理规则,定义了对alias的简单的简单增改删等操作。
SimpleAlliasRegistry: 主要是用map作为alias的缓存,并对接口AliasRegistry进行实现。
SingletonBeanRegistry: 定义对单例的注册及获取。
BeanFactory: 定义获取bean及bean的各种属性
DefaultSingletonBeanRegistry: 对接口SingletonBeanRegistry各函数的实现。
HierarchicalBeanFactory: 继承BeanFactory,也就是在BeanFactory的基础上定义了对parentFactory的支持。
BeanDefinitionRegistry: 定义对BeanDefinition的各种增改删操作。BeanDefinition中定义的属性有诸如类名、sccope、属性、构造函数参数列表、依赖的bean、是否单例类、
是否懒加载等,其实就是将Bean的定义信息存储到这个BeanDefinition相应的属性中,之后对Bean的操作就是直接对BeanDefinition进行的。
FactoryBeanRegistrySupport: 在DefaultSingletonBeanRegistry基础上增加了对FactoryBean的特殊处理功能。
ConfigurableBeanFactory: 提供配置Factory的各种方法。
ListableBeanFactory: 根据各种条件获得bean的配置清单。
AbstractBeanFactory: 综合FactoryBeanRegistrySupport和ConfigurableBeanFactory的功能。
AutowireCapableBeanFactory: 提供创建bean自动注入,初始化以及应用bean的后置处理器
AbstractAutowireCapableBeanFactory: 综合AbstractBeanFactory并对接口Autowire,CapableBeanFactory进行实现。
ConfigurableListableBeanFactory: BeanFactory配置清单,指定忽略类型及接口等。
而我们的核心类DefaultListableBeanFactory就是综合了上面所有的功能,主要负责了Bean注册后的处理。
层次结构
DefaultListableBeanFactory继承了AbstractAutowireCapalbeBeanFactory以及实现了BeanDefinitionRegistry,ConfigurableListableBeanFactory接口,是Spring注册及加载bean的默认实现。
4.DefaultListableBeanFactory一些常用方法:
public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter)
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons,
boolean allowEagerInit)
在Spring中,凡是以do开头的方法一般都是细节上的逻辑处理,也就是具体的实现代码。
关于doResolveDependency实现的具体逻辑
a.首先将 beanName 和 requiredType 作为参数,并尝试从 BeanFactory 中获取与此对于的 bean。若获取成功,就可以提前结束 doResolveDependency 的逻辑。
b.处理 @value 注解
c.解析数组、List、Map 等类型的依赖,如果解析结果不为空,则返回结果
d.根据类型查找合适的候选项
e.如果候选项的数量为0,则抛出异常。为1,直接从候选列表中取出即可。若候选项数量 > 1,则在多个候选项中确定最优候选项,若无法确定则抛出异常
f.若候选项是 Class 类型,表明候选项还没实例化,此时通过 BeanFactory.getBean 方法对其进行实例化。若候选项是非 Class 类型,则表明已经完成了实例化,此时直接返回即可。
以上出处:https://blog.csdn.net/Taylar_where/article/details/90547570
三、finishBeanFactoryInitialization 详解 https://blog.csdn.net/qq_44836294/article/details/107795639
简单流程:通过反射实例化Bean --> 填充属性 --> 初始化 --> 完整Bean
中间会产生循环依赖问题:使用三级缓存解决
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { ... // 从上至下 分表代表这“三级缓存” private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); //一级缓存 private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); // 二级缓存 private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); // 三级缓存 ... /** Names of beans that are currently in creation. */ // 这个缓存也十分重要:它表示bean创建过程中都会在里面呆着~ // 它在Bean开始创建时放值,创建完成时会将其移出~ private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); /** Names of beans that have already been created at least once. */ // 当这个Bean被创建完成后,会标记为这个 注意:这里是set集合 不会重复 // 至少被创建了一次的 都会放进这里~~~~ private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256)); }
注:AbstractBeanFactory继承自DefaultSingletonBeanRegistry
- singletonObjects:用于存放完全初始化好的 bean,从该缓存中取出的 bean 可以直接使用
- earlySingletonObjects:提前曝光的单例对象的cache,存放原始的 bean 对象(尚未填充属性),用于解决循环依赖
- singletonFactories:单例对象工厂的cache,存放 bean 工厂对象,用于解决循环依赖
出处:https://blog.csdn.net/fedorafrog/article/details/104550165