本节讲 Spring bean初始化(3) - ApplicationContext
ApplicationContext和BeanFactory都是用于加载Bean的,但是项目中基本都是使用ApplicationContext,原因是它包括了BeanFactory的所有功能,并且进行了扩展,ApplicationContext初始化过程中会完成所有的单例( no-lazy-init) 的初始化
ApplicationContext ctx = new ClassPathXmlApplicationContext("/spring-code-test.xml"); SysArgDAO bean = (SysArgDAO) ctx.getBean("sysArgDAO");
下面看一下 ClassPathXmlApplicationContext 的具体代码实现
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); // 支持数组方式传入 xml 配置文件 setConfigLocations(configLocations); if (refresh) { // 核心逻辑 refresh(); } }
refresh包括了核心逻辑,在类 AbstractApplicationContext 中
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // 这一步会完成 xml载入,并且将属性放入 beanFactory, 完成了 《Spring bean初始化(1)》 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); // 执行 BeanFactoryPostProcessor, 这是 applicationcontext 扩展的功能,保证在bean初始化前做定制 // 比如 PropertyPlaceholderConfigurer,就会处理xml中的变量解析替换(比如 <value>${jdbc.url}</value> ),保证bean初始化之前完成 invokeBeanFactoryPostProcessors(beanFactory); // 注册 BeanPostProcessor 方法,可以将配置文件中的 BeanPostProcessor 实现直接注册,方法会在getBean的流程中调用,执行 applicationcontext 定制的方法对bean处理 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(); // 实例化所有 non-lazy-init 单例 finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); }