spring装配Bean过程
主要流程:
// Prepare this context for refreshing.
//1 准备刷新工作
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 2 实例化BeanFactory,将配置文件的信息装入到容器的Bean定义的注册表(BeanDefinitionRegistry中),此时Bean还未初始化
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 3 准备BeanFactory 主要是加载一些类
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 4 留作子类实现
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 5 调用工厂后处理器
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//6 注册bean后处理器
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
//7 初始化消息源
initMessageSource();
// Initialize event multicaster for this context.
//8 初始化事件广播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//9 钩子方法
onRefresh();
// Check for listener beans and register them.
// 10 注册监听器
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//11 完成bean实例化(除lazy-init),并放入缓存中
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 12 广播刷新事件
finishRefresh();
}
一、prepareRefresh():准备工作。
preProcessXml(root);
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);
二、ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet<EncodedResource>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
finally {
inputStream.close();
}
}
try {
Document doc = doLoadDocument(inputSource, resource);
return registerBeanDefinitions(doc, resource);
}
protected void doRegisterBeanDefinitions(Element root) {
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
return;
}
}
}
preProcessXml(root);
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);
this.delegate = parent;
}
- 默认元素
- 用户自定义元素
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
- public static final String IMPORT_ELEMENT = "import";
public static final String ALIAS_ELEMENT = "alias";
public static final String BEAN_ELEMENT = "bean";
public static final String NESTED_BEANS_ELEMENT = "beans";
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String aliase : aliases) {
registry.registerAlias(beanName, aliase);
}
}
}
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "'beanName' must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
this.beanDefinitionMap.put(beanName, beanDefinition);
}
/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
三、prepareBeanFactory(beanFactory):加载一些类资源
四、postProcessBeanFactory(beanFactory):留作子类实现,这里为空
五、invokeBeanFactoryPostProcessors(beanFactory):调用BeanFactoryPostProcessor接口处理beanFactory.
- org.springframework.beans.factory.config.PropertyPlaceholderConfigurer:属性占位符(${user})
- org.springframework.beans.factory.config.PropertyOverrideConfigurer
- org.springframework.beans.factory.config.CustomEditorConfigurer:用来注册自定义的属性编辑器
public interface BeanFactoryPostProcessor {
/**
*在其标准初始化后修改应用程序上下文的内部bean工厂。 所有bean定义都将被加载,但是没有bean将被实例化。
*这允许覆盖或添加属性,即使是急切地初始化bean。
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
<bean id="myBean" class="uodut.spring3x.MyBean">
<property name="desc" value="这里通过自定义MyBeanFactoryPostProcessorImpl来动态改变mark的值"></property>
<property name="mark" value="initMark"></property>
</bean>
<bean id="myBeanFactoryPostProcessor" class="uodut.spring3x.MyBeanFactoryPostProcessorImpl"/>
public class MyBeanFactoryPostProcessorImpl implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition bd = beanFactory.getBeanDefinition("myBean");
System.out.println("属性值:" + bd.getPropertyValues().toString());
MutablePropertyValues propertyValues = bd.getPropertyValues();
if (propertyValues.contains("mark")) {
propertyValues.addPropertyValue("mark", "initMark->afterMark");
}
}
}
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("BeanTest.xml");
MyBean bean = (MyBean) context.getBean("myBean");
System.out.println("描述:" + bean.getDesc());
System.out.println("备注:" + bean.getMark());
}
属性值:PropertyValues: length=2; bean property 'desc'; bean property 'mark'
描述:这里通过自定义MyBeanFactoryPostProcessorImpl来动态改变mark的值
备注:initMark->afterMark
六、registerBeanPostProcessors(beanFactory);注册BeanPostProcessors
public class MyBean implements InitializingBean{
public void afterPropertiesSet() throws Exception {
System.out.println("调用afterPropertiesSet方法");
this.desc = "在初始化方法中修改之后的描述信息";
}
}
public class MyBeanPostProcessorImpl implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor,对象" + beanName + "调用初始化方法之前的数据: " + bean.toString());
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor,对象" + beanName + "调用初始化方法之后的数据:" + bean.toString());
return bean;
}
}
属性值:PropertyValues: length=2; bean property 'desc'; bean property 'mark'
调用setDesc方法
调用setMark方法
BeanPostProcessor,对象myBean调用初始化方法之前的数据: [描述:原始描述信息, 备注:initMark->afterMark]
调用afterPropertiesSet方法
调用initMethod方法
BeanPostProcessor,对象myBean调用初始化方法之后的数据:[描述:在初始化方法中修改之后的描述信息, 备注:initMark->afterMark]
描述:在初始化方法中修改之后的描述信息
备注:initMark->afterMark
七、initMessageSource();初始化消息源
八、initApplicationEventMulticaster();初始化应用上下文事件广播
九、onRefresh();初始化其他特殊的bean,这是一个钩子方法。
十、registerListeners();注册监听器
十一、finishBeanFactoryInitialization(beanFactory);初始化所有单实例的Bean,使用lazy-init的bean除外。初始化Bean后,将它们放入Spring容器的缓存中。
十二、finishRefresh();创建上下文刷新事件,事件广播器负责将这些事件广播到每个注册的事件监听器中。
spring容器从加载配置文件到创建出一个完整的Bean的流程

- 《spring 3.x企业应用开发实战》
- http://blog.csdn.net/caihaijiang/article/details/35552859
spring装配Bean过程的更多相关文章
- Spring装配Bean的过程补充
对上一篇的<Spring装配Bean的过程>的过程说一下,不然真产生了误区. 误区在哪里呢?那就是spring bean的作用域问题. 说哈常用的两种作用域:默认是scope = sing ...
- Spring装配Bean的过程
首先说一个概念:“懒加载” 懒加载:就是我们在spring容器启动的是先不把所有的bean都加载到spring的容器中去,而是在当需要用的时候,才把这个对象实例化到容器中. spring配置文件中be ...
- Spring 装配Bean
Spring 装配Bean 装配解释: 创建应用对象之间协作关系的的行为通常称为装配(wiring),这也是依赖注入的本质 依赖注入是Spring的基础要素 一 : 使用spring装配Bean基础介 ...
- Spring 装配Bean入门级
装配解释: 创建应用对象之间协作关系的的行为通常称为装配(wiring),这也是依赖注入的本质 依赖注入是Spring的基础要素 一 : 使用spring装配Bean基础介绍 1 :声明Bean B ...
- Spring装配bean
Spring配置的可选方案 Spring提供了如下三种装配机制: (1)在XML中显式配置 (2)在Java中显式配置 (3)隐式的bean发现机制和自动装配 Spring有多种方式可以装配bean, ...
- Spring装配Bean之XML装配bean
在Spring刚出现的时候,XML是描述配置的主要方式,在Spring的名义下,我们创建了无数行XML代码.在一定程度上,Spring成为了XML的同义词. 现在随着强大的自动化配置和Java代码的配 ...
- 【转】spring 装配Bean中构造参数的注入
转载自:http://www.bianceng.cn/Programming/Java/201307/37027.htm spring 装配Bean中构造参数的注入 spring装配bean中还有一种 ...
- Spring装配Bean之组件扫描和自动装配
Spring从两个角度来实现自动化装配: 组件扫描:Spring会自动发现应用上下文中所创建的bean. 自动装配:Spring自动满足bean之间的依赖. 案例:音响系统的组件.首先为CD创建Com ...
- spring装配bean的三种方式及其混合装配
在spring容器中装配bean有三种基本方式和混合装配方式: 隐式的bean自动发现机制和自动装配 在java中进行显式配置 在xml中配置 混合装配(在多个java文件中配置.在JavaConfi ...
随机推荐
- visual studio 2015 warning MSB3246
在我们很高兴的按下 本地计算机运行 按钮,希望看到我们程序运行的时候,垃圾vs就告诉我们,你的程序出现了问题,问题就是: warning MSB3246: 解析的文件包含错误图像.无元数据或不可访问. ...
- Spring 为Bean对象执行初始化和销毁方法
1)初始化: ①可以利用<bean>元素的init-method="方法名"属性指定初始化方法. ②指定的初始化方法是在构造方法调用后自动执行.若非单例模式,则每创建一 ...
- JavaScript面向对象深入理解原型
原型模式 function Person(){ } Person.prototype.name="Ewarm"; Person.prototype.age="29&quo ...
- MongoDB用户权限管理
创建用户账号: (roles参数指定了用户的角色以及这个账号授权的数据库,在同一个数据库中不能同时创建两个用户名相同的账号) Mongodb内置的用户角色: 数据库用户角色:read.readWrit ...
- Akka(33): Http:Marshalling,to Json
Akka-http是一项系统集成工具.这主要依赖系统之间的数据交换功能.因为程序内数据表达形式与网上传输的数据格式是不相同的,所以需要对程序高级结构化的数据进行转换(marshalling or se ...
- 根据文字计算出label的高度
ios7.0之前用: [strtestsizeWithFont:ContentFontconstrainedToSize:CGSizeMake(ScreenWeight -20, 1000) line ...
- xml读取一行数据
#include<map>#include<iostream>#include<fstream>#include<string>using namesp ...
- SSM框架中的注解,配置和控制器相关笔记
常规SSM实例 探索SSM理论的前提,应该是在对框架基础的运作方式有一定了解,以下是个人Android后台项目,用SSM框架快速搭建,以下是代码,主要 观察结构. 代码结构: model实体类 Ida ...
- C++求出旋转数组的最小数字
今天遇到这么一道题目,感觉很有意思,要记下来! 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4 ...
- scanf和cin性能的比较
我的实验机器配置是: 处理器:Intel(R) Core(TM) i3-7100U CPU @ 2.40GHz 2.40GHz 随机访问存储器:4.00GB 操作系统:Windows10 集成开发环境 ...