Spring ApplicationContext下的refresh()方法
Posted kl0428
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring ApplicationContext下的refresh()方法相关的知识,希望对你有一定的参考价值。
public class BeanTest{ @Test public void test(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); System.out.println(applicationContext); Student student = (Student)applicationContext.getBean("student"); student.play(); System.out.println(student); //关闭容器 ((AbstractApplicationContext)applicationContext).close(); } }
调用ApplicationContext,执行refresh()
@Override 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(); } } }
1、刷新容器前的预处理prepareRefresh
// Initialize any placeholder property sources in the context environment. //初始化一些属性设置 initPropertySources(); // Validate that all properties marked as required are resolvable: // see ConfigurablePropertyResolver#setRequiredProperties //校验属性的合法性 getEnvironment().validateRequiredProperties(); // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... //保存容器中的早期事件的容器 Set 集合 this.earlyApplicationEvents = new LinkedHashSet<>();
2、获取 beanFactory ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//构造一个 beanFactory
this.beanFactory = new DefaultListableBeanFactory();
//获取 BeanFactory 返回的上一步构 GenericApplicationContext 类构造器创建的 beanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//返回 beanFactory 【ConfigurableListableBeanFactory 的实例实例对象】
return beanFactory;
3、beanFactory 的预准备工作 prepareBeanFactory(beanFactory);
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig)); beanFactory.ignoreDependencyInterface(ServletContextAware.class); beanFactory.ignoreDependencyInterface(ServletConfigAware.class); WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext); WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig); }
4、beanFactory 准备完成的后置处理工作 postProcessBeanFactory(beanFactory);
5、执行 beanFactoryPostProcessors 方法 invokeBeanFactoryPostProcessors(beanFactory);
执行 invokeBeanFactoryPostProcessors 的方法
BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor
再执行 BeanFactoryPostProcessors 的方法
beanFactory.preInstantiateSingletons();
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
for (String beanName : beanNames) {
...
}
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
...
}
if (isFactoryBean(beanName)) {
...
}
Object sharedInstance = getSingleton(beanName);
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between ‘" + beanName + "‘ and ‘" + dep + "‘");
}
registerDependentBean(dep, beanName);
getBean(dep);
}
}
(4)、
进入单实例 bean 的创建流程 return createBean(beanName, mbd, args);
以上是关于Spring ApplicationContext下的refresh()方法的主要内容,如果未能解决你的问题,请参考以下文章
Spring -- Spring相关API (ApplicationContext getBean)
spring BeanFactory 与ApplicationContext
BeanFactory and ApplicationContext in Spring