Spring源码学习之容器篇
来源:互联网 发布:pr cc mac 2017破解版 编辑:程序博客网 时间:2024/06/05 04:12
一、ApplicationContext系列浏览
ApplicationContext接口体系如图:
其中主要分为ApplicationContext和WebApplicationContext
1、ApplicationContext接口
//从接口ApplicationContext中可以看出,该接口扩展自对象工厂体系,主要实现的也还是一个对象工厂功能public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver { ... }
2、ConfigurableApplicationContext接口
//该接口规范了一个有生命周期、可配置的ApplicationContextpublic interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable { ... }
3、AbstractApplicationContext
//AbstractApplicationContext提供了一个基本的ApplicationContext的实现,这其中实现了大部分ApplicationContext的功能public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean { ... //--------------------------------------------------------------------- // 在这里实现了容器的生命周期控制,可以看出容器的生命周期都由LifecycleProcessor来管理 // 的,而LifecycleProcessor对象会在启动容器时进行初始化,如果有自定义的使用自定义的, // 没有的话会使用DefaultLifecycleProcessor //--------------------------------------------------------------------- @Override public void start() { getLifecycleProcessor().start(); publishEvent(new ContextStartedEvent(this)); } @Override public void stop() { getLifecycleProcessor().stop(); publishEvent(new ContextStoppedEvent(this)); } @Override public boolean isRunning() { return (this.lifecycleProcessor != null && this.lifecycleProcessor.isRunning()); } ... }
4、AbstractRefreshableApplicationContext
//AbstractRefreshableApplicationContext主要实现了更新容器的功能,refreshBeanFactory主要是重新加载对象工厂中的beanspublic abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext { ... @Override 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); } } ... }
5、AbstractRefreshableConfigApplicationContext
//AbstractRefreshableConfigApplicationContext主要暴漏了一些设置配置路径相关的接口public abstract class AbstractRefreshableConfigApplicationContext extends AbstractRefreshableApplicationContext implements BeanNameAware, InitializingBean { ... //如果实例化时未refresh 会在对象工厂中设置完毕参数进行refresh、保证容器正常启动 @Override public void afterPropertiesSet() { if (!isActive()) { refresh(); } } ... }
6、AbstractXmlApplicationContext
//AbstractXmlApplicationContext 主要实现了xml方式加载对象配置的方式public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext { ... @Override protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // Create a new XmlBeanDefinitionReader for the given BeanFactory. XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // Configure the bean definition reader with this context's // resource loading environment. beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); // Allow a subclass to provide custom initialization of the reader, // then proceed with actually loading the bean definitions. initBeanDefinitionReader(beanDefinitionReader); loadBeanDefinitions(beanDefinitionReader); } ... }
6、ClassPathXmlApplicationContext
//ClassPathXmlApplicationContext 就是xml方式配置对象的具体实现类啦,该类实现的是使用ClassPathResource作为配置资源读取的方式,另外还有FileSystemXmlApplicationContext这两个实现的区别就在于资源Resource的实现不同,一个是ClassPathResource一个是FileSystemResourcepublic class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext { ... }
二、使用ClassPathXmlApplicationContext 启动容器的顺序
1、启动方式
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( new String[] { "/META-INF/spring/applicationContext.xml" });context.start();
2、启动流程
1、构造ClassPathXmlApplicationContext 对象
//最终是通过这个构造方法进行实例化 public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { //建立关系 super(parent); //设置配置资源路径 setConfigLocations(configLocations); if (refresh) { //初始化容器 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. //获取对象工厂,如果没有就创建一个,默认实现是DefaultListableBeanFactory,并会加载好所有的对象配置信息等 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. //在这里会初始化一个ApplicationContext的DefaultLifecycleProcessor 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(); } } }
2、启动容器
context.start();
到这里其实是由DefaultLifecycleProcessor 进行处理对象工厂里 所有Lifecycle.class类型的对象
进行生命周期管理及启动操作。
在容器里的对象在初始化时就已经实例化完毕
//容器默认委托的生命周期处理器public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactoryAware { ... private void startBeans(boolean autoStartupOnly) { //从对象工厂中获取类型为Lifecycle.class的对象 Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans(); Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>(); //将实现生命周期的bean进行分组处理,相同的phase值封装到一个LifecycleGroup中 for (Map.Entry<String, ? extends Lifecycle> entry : lifecycleBeans.entrySet()) { Lifecycle bean = entry.getValue(); if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) { int phase = getPhase(bean); LifecycleGroup group = phases.get(phase); if (group == null) { group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly); phases.put(phase, group); } group.add(entry.getKey(), bean); } } //按phase值进行排序 启动,实现启动顺序的控制(升序,没有实现phase的默认为0) if (phases.size() > 0) { List<Integer> keys = new ArrayList<Integer>(phases.keySet()); Collections.sort(keys); for (Integer key : keys) { phases.get(key).start(); } } } ...}
0 1
- Spring源码学习之容器篇
- spring源码学习之容器监听器篇
- Spring源码学习-容器初始化之FileSystemXmlApplicationContext(一)构造函数
- Spring源码学习之容器的功能扩展
- spring学习之IOC容器
- spring 源码学习-容器初始化-1
- spring 源码学习-容器初始化-2
- 【Spring源码解析】之IOC容器
- Spring IOC源码详解之容器初始化
- Spring IOC源码详解之容器初始化
- Spring IOC源码详解之容器初始化
- spring源码学习之路---IOC容器初始化要义之bean定义载入(五)
- spring源码学习之路---IOC容器初始化要义之bean定义载入
- spring源码学习之路---IOC容器初始化要义之bean定义载入(五)
- spring源码学习之路---IOC容器初始化要义之bean定义载入(四)
- spring学习笔记:Spring IOC容器,Spring源码
- spring学习之---使用spring容器
- spring学习之---spring容器中的Bean
- sharding-jdbc集成spring+mybatis分表分库
- 默认页面index.jsp跳转到*.action
- VS2015安装Qt VS Tools
- C++上机报告(项目3杨辉三角)
- iOS之UILabel的操作集合
- Spring源码学习之容器篇
- C#学习之(三)C#解析Json文件的方法
- Linux 常用shell命令
- Unity3D 导入贴图、模型等资源文件时自动设置参数
- yii日历选取时间段
- 给初学者的RxJava2.0教程(七)
- php概率算法
- Java如何打印数组之Array.ToString()
- 剑指offer编程题(1):数组