古人已用三冬足,年少今开万卷余。这篇文章主要讲述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();
【Spring ApplicationContext下的refresh()方法】//返回 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
先执行 BeanDefinitionRegistryPostProcessor 的方法
再执行 BeanFactoryPostProcessors 的方法 6、注册 BeanPostProcessors 【 Bean 的后置处理器 】registerBeanPostProcessors(beanFactory); 优先级接口PriorityOrdered 和 Ordered 7、初始化 MessageSource 组件 initMessageSource(); 8、初始化事件派发器 initApplicationEventMulticaster(); 9、留给子容器(子类)onRefresh(); 10、给容器中将所有项目里面的ApplicationListener注册进来 registerListeners(); 11、初始化所有剩下的单实例 Bean(没有配置赖加载的 lazy!=true) finishBeanFactoryInitialization(beanFactory); 1> 、初始化所有剩下的单实例bean
beanFactory.preInstantiateSingletons();
2>
、将容器中所有的 bean 加入到 List中
List<
String>
beanNames = new ArrayList<
String>
(this.beanDefinitionNames);
3>
、遍历该 List
for (String beanName : beanNames) {
...
}
4> 、获取 bean 定义信息
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
5>
、bean 不是抽象的、是单例的、非懒加载的
if (!bd.isAbstract() &
&
bd.isSingleton() &
&
!bd.isLazyInit()) {
...
}
6> 、是否为 FactoryBean ,是则调用 FactoryBean 的创建方法,否则执行 getBean() 方法
if (isFactoryBean(beanName)) {
...
}
7> 、调用 getBean() 方法 -> 内部再调用 doGetBean() 方法 (1)、尝试从从缓存中获取 bean
Object sharedInstance = getSingleton(beanName);
(2)、获取 bean 定义信息
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
(3)、判断是否有其他依赖,如果有其他依赖,注册依赖的 bean 并调用 getBean() 方法创建
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);
推荐阅读
- 在做H5APP时的高清屏解决方案
- 记一次腾讯Android一面,拿走不谢!
- appium-java,连接真机启动微信(适应于安卓8.0及以上,新版appium)
- SAS格式化数据集详细图解
- SAS-合并数据集解析图解
- 在SAS中写入数据集图解
- 在SAS中读取原始数据图解
- SAS对多个变量排序详细图解
- 在SAS数据集中排序