说说 Spring 容器的技术内幕「建议收藏」

说说 Spring 容器的技术内幕「建议收藏」说说 Spring 容器的技术内幕

欢迎大家来到IT世界,在知识的湖畔探索吧!

Spring 的 AbstractApplicationContext 是 ApplicationContext 的抽象实现类,这个类的 refresh() 方法定义了 Spring 容器在加载配置文件之后的处理过程:

public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing.
prepareRefresh(); // Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory); // Initialize message source for this context.
initMessageSource(); // Initialize event multicaster for this context.
initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses.
onRefresh(); // Check for listener beans and register them.
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...
resetCommonCaches();
}
}
}

欢迎大家来到IT世界,在知识的湖畔探索吧!

下面列出重要的方法名与说明:

方法名 说明
obtainFreshBeanFactory() 根据配置文件初始化 BeanFactory;这个方法内部,首先调用 refreshBeanFactory() 刷新 BeanFactory,然后调用 getBeanFactory() 获取 BeanFactory,这两个方法都是由具体的子类实现的;在此会把配置信息装载到 BeanDefinitionRegistry。
invokeBeanFactoryPostProcessors(beanFactory) 根据反射机制,调用工厂后处理器。
registerBeanPostProcessors(beanFactory) 根据反射机制,调用 Bean 后处理器。
initMessageSource() 初始化容器的国际化消息资源。
initApplicationEventMulticaster() 初始化应用上下文的事件广播器。
onRefresh() 初始化特殊的 Bean,这是一个钩子方法,子类会借由这个方法实现一些特殊的操作。
registerListeners() 注册事件监听器。
finishBeanFactoryInitialization(beanFactory) 初始化所有的单实例 Bean 到容器的缓存池中(不包含设为懒加载的 Bean)。
finishRefresh() 创建上下文刷新事件,事件广播器会把这一事件通知到所有注册了该事件的监听器。

说说 Spring 容器的技术内幕「建议收藏」

容器启动工作流程

重点罗列如下:

1、容器会扫描 BeanDefinitionRegistry 中的 BeanDefinition,通过使用 Java反射机制识别出 Bean 的工厂后置处理器(实现了 BeanFactoryPostProcessor 接口的类),然后调用这些工厂后置处理器对 BeanDefinition 进行加工处理,这里包含两项操作:

  • 解析使用了占位符的 <bean> 元素标签,获取最终的配置值。

  • 通过 Java 反射机制找出所有属性编辑器(实现了 java.beans.PropertyEditor 接口的类),把它们添加到容器的属性编辑器注册表(PropertyEditorRegistry)中。

2、容器使用 BeanWrapper 来注入属性,它定义了很多以 Java 反射机制操作 Bean 的方法。

Spring 的接口层描述了容器中的重要组件以及之间的协作关系;它的继承体系则逐一实现了这些组件的各项功能。

这些组件按角色可划分为:

  • 实体组件 – 比如 Resource、BeanDefinition、PropertyEditor 等等;在流程中,它们是被加工或者被消费的对象。

  • 加工组件 – 比如 ResourceLoader、BeanDefinitionReader、BeanFactoryPostProcessor、InstantiationStrategy 和 BeanWrapper 等等;在流程中,它们会对实体组件进行加工处理。

1 Bean 定义类(BeanDefinition)

BeanDefinition 是配置文件中 <bean> 元素标签在容器中的内部表示。它们之间的对应关系是:

<bean> 元素标签属性 BeanDefinition 属性
class beanClass
scope scope
lazy-init lazyInit

说说 Spring 容器的技术内幕「建议收藏」

BeanDefinition 类的继承结构

RootBeanDefinition 对应的是一般性的 <bean> 元素标签。配置文件是支持配置 <bean> 之间的继承关系的。父 bean 用的即是 RootBeanDefinition,而子 bean 用的是 ChildBeanDefinition。AbstractBeanDefinition 是它们之间所共有信息的抽象。

Spring 会把这些 BeanDefinition 注册到 BeanDefinitionRegistry 中,以后就可以直接从 BeanDefinitionRegistry 中获取这些定义信息。一般情况下,只在启动容器时加载与解析 BeanDefinition(除了刷新或重启容器)。我们也可以通过编程的方式在运行期间调整 BeanDefinition 的定义。

BeanDefinition 的创建过程,分为两步:

  1. 使用 BeanDefinitionReader 来读取包含配置信息的 Resource,然后通过 XML 解析器解析配置信息的 DOM 对象,生成基本的 BeanDefinition 对象。

  2. 利用在容器中注册的 BeanFactoryPostProcessor 对 BeanDefinition 进行加工处理,把以占位符表示的配置信息解析为最终的实际值。

2 初始化策略类(InstantiationStrategy)

InstantiationStrategy 会根据 BeanDefinition 创建对应 Bean 的实例。子所以采用策略模式,是为了方便采用不同的实例化策略。

说说 Spring 容器的技术内幕「建议收藏」

InstantiationStrategy 接口继承结构

SimpleInstantiationStrategy 会根据 Bean 实现类的默认构造函数或带参构造函数或工厂方法来创建 Bean 的实例。

CglibSubclassingInstantiationStrategy 扩展了 SimpleInstantiationStrategy ,它是利用 CGLib 类库动态生成 Bean 的子类,再通过这个子类来创建 Bean 的实例。

InstantiationStrategy 只实例化 Bean,Bean 中的属性初始化工作交由 BeanWrapper 来完成。

3 属性初始化(BeanWrapper )

BeanWrapper 可以看作是一个代理,由它来完成 Bean 属性的初始化工作。

说说 Spring 容器的技术内幕「建议收藏」

BeanWrapper 类继承结构

BeanWrapper 有两个顶级接口:

  • PropertyAccessor – 定义了访问 Bean 属性的方法。

  • PropertyEditorRegistry – 属性编辑器注册表。

所以 BeanWrapper 的实现类 BeanWrapperImpl 具有三种身份:

  • Bean 包裹器。

  • 属性访问器。

  • 属性编辑器注册表。

BeanWrapperImpl 内部封装了待处理 Bean 以及可设置 Bean 属性的编辑器,它使用 Spring 的 BeanUtils 工具类(反射实现)来设置属性。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/22839.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信