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