了解spring 的原理,一般从 官方提供的运行机制的图,然后根据代码 进行源码分析,就可以了,这里先从spring mvc 启动开始分析。先来看看web.xml 的配置吧。这里基于spring 3.2
<!-- 启动监听 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/classes/META-INF/spring/applicationContext*.xml</param-value> </context-param> <!-- app 请求 --> <servlet> <servlet-name>SpringMVCServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/config/app-config.xml </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SpringMVCServlet</servlet-name> <url-pattern>/c/*</url-pattern> </servlet-mapping>
上面主要有两个东西:
1.ContextLoaderListener 监听器:
2.DispatcherServlet 控制器:
在启动的时候,如果观察启动日志 就能发现,1.首先启动,2.然后是DispatcherServlet ,我们来看看这两个东西 在初始化的时候干了什么?
public class ContextLoaderListener extends ContextLoader implements ServletContextListener { private ContextLoader contextLoader; // 这是实现了ServletContextListener 监听,一个初始化方法 和一个销毁的方法 public void contextInitialized(ServletContextEvent event) { // 这里已经废弃,不用了,一直未null this.contextLoader = createContextLoader(); if (this.contextLoader == null) { this.contextLoader = this; } // 主要看看初始化,他到底做了什么,进入源码分析 this.contextLoader.initWebApplicationContext(event.getServletContext()); } public void contextDestroyed(ServletContextEvent event) { // ....略 } }
进入ContextLoader,找到initWebApplicationContext 方法:
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) { // 这里只贴方法 // 先判断 是否已经加载过了 if (servletContext.getAttribute( WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) { // ... } // 创建 WebApplicationContext 对象,详细的看 create 方法 if (this.context == null) { this.context = createWebApplicationContext(servletContext); } // 这一步就是加载你xml 配置<context-param> 里面的内容,默认是application... // 看后面他是如何实现的。 if (this.context instanceof ConfigurableWebApplicationContext) { configureAndRefreshWebApplicationContext((ConfigurableWebApplicationContext)this.context, servletContext); } } }
createWebApplicationContext 方法,负责创建 WebApplicationContext 上下文对象
protected WebApplicationContext createWebApplicationContext(ServletContext sc) { // 这里拿到XmlWebApplicationContext 的对象 Class<?> contextClass = determineContextClass(sc); // 这里转成他的扩展接口对象ConfigurableWebApplicationContext ,多加了一些获得配置信息的方法 // 至于这里一步的原因我不是很明白,大概是为了一个兼容的的问题,以前的设计这里会出错。 ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass); return wac; } // 这个类默认创建指定处理xml/bean 的类对象 protected Class<?> determineContextClass(ServletContext servletContext) { // 这里表示你在web.xml 可以手动自己写一个需要处理的加载类对象, // 默认是XmlWebApplicationContext // 如何你需要额外的加载,一般是继承XmlWebApplicationContext 行了 String contextClassName = servletContext.getInitParameter( CONTEXT_CLASS_PARAM); if (contextClassName != null) { try { // 这里是默认是获得当前线程的加载器 return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader()); } } else { // 这里是通过properties 进行加载,defaultStrategies 是一个静态类 // 默认获得当前目录下ContextLoader.properties里面的XmlWebApplicationContext 类路径 contextClassName = defaultStrategies.getProperty( WebApplicationContext.class.getName()); try { // 这里同样通过类路径装载类,加载器是ContextLoader return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader()); } } }
这里主要负责加载xml 文件
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) { // 这里官方解释 和EJB 有关系,具体请看API。类似我们这种纯web 中,这里一般都是空的 ApplicationContext parent = loadParentContext(sc); // 这里就是加载我们配置的contextConfigLocation 的参数,这也是为什么需要这个名字的原因 // 同时里面所有对应的xml文件都会找到,对应的参数值是: // classpath*:com/home/config/spring/spring-*.xml String initParameter = sc.getInitParameter(CONFIG_LOCATION_PARAM); if (initParameter != null) { wac.setConfigLocation(initParameter); } // 这里是定制自己的context,也就是你可以扩展,这里我是没扩展,所以没用,不解释 customizeContext(sc, wac); // 这里方法,在子类 AbstractApplicationContext 里面 // 它负责加载xml properties 以及database schema ,看看他是如何操作的! wac.refresh(); }
相关推荐
1.2.2 使用Spring Initializr初始化Spring Boot项目 10 1.3 小结 18 第2章 开发第一个应用程序 19 2.1 运用Spring Boot 19 2.1.1 查看初始化的Spring Boot新项目 21 2.1.2 Spring Boot项目构建过程解析 ...
在这个上下文的基础上,和web MVC相关还会有一个上下文来保存控制器之类的MVC对象,这样就构成了一个层次化的上下文结构。在web容器中启动Spring应用程序就是一个建立这个上下文体系的过程。Spring为web应用提供了上...
3.3.5. 延迟初始化bean 3.3.6. 自动装配(autowire)协作者 3.3.6.1. 设置Bean使自动装配失效 3.3.7. 依赖检查 3.3.8. 方法注入 3.3.8.1. Lookup方法注入 3.3.8.2. 自定义方法的替代方案 3.4. bean的作用域 3.4.1. ...
3.3.5. 延迟初始化bean 3.3.6. 自动装配(autowire)协作者 3.3.7. 依赖检查 3.3.8. 方法注入 3.4. bean的作用域 3.4.1. Singleton作用域 3.4.2. Prototype作用域 3.4.3. 其他作用域 3.4.4. 自定义作用域 ...
3.3.4. 延迟初始化bean 3.3.5. 自动装配(autowire)协作者 3.3.6. 依赖检查 3.3.7. 方法注入 3.4. Bean的作用域 3.4.1. Singleton作用域 3.4.2. Prototype作用域 3.4.3. Singleton beans和prototype-bean的...
3.3.5. 延迟初始化bean 3.3.6. 自动装配(autowire)协作者 3.3.7. 依赖检查 3.3.8. 方法注入 3.4. bean的作用域 3.4.1. Singleton作用域 3.4.2. Prototype作用域 3.4.3. 其他作用域 3.4.4. 自定义作用域 ...
3.3.4. 延迟初始化bean 3.3.5. 自动装配(autowire)协作者 3.3.6. 依赖检查 3.3.7. 方法注入 3.4. Bean的作用域 3.4.1. Singleton作用域 3.4.2. Prototype作用域 3.4.3. Singleton beans和prototype-bean的...
2.7 自定义Bean初始化和析构 72 2.7.1 问题 72 2.7.2 解决方案 72 2.7.3 工作原理 72 2.8 用Java Config简化XML配置 77 2.8.1 问题 77 2.8.2 解决方案 77 2.8.3 工作原理 77 2.9 使Bean感知容器 ...
2.7 自定义Bean初始化和析构 72 2.7.1 问题 72 2.7.2 解决方案 72 2.7.3 工作原理 72 2.8 用Java Config简化XML配置 77 2.8.1 问题 77 2.8.2 解决方案 77 2.8.3 工作原理 77 2.9 使Bean感知容器 ...
8.4.3 改变初始化和销毁方式 8.4.4 改变异常处理的方式 8.5 小结 第九章 CVS使用指南 9.1 CVS介绍 9.1.1 CVS简介 9.1.2 为什么要使用CVS 9.2 建立CVS的开发环境 9.2.1 下载CVS 9.2.2 配置CVS 9.3 CVS的使用方法 ...
8.4.3 改变初始化和销毁方式 8.4.4 改变异常处理的方式 8.5 小结 第九章 CVS使用指南 9.1 CVS介绍 9.1.1 CVS简介 9.1.2 为什么要使用CVS 9.2 建立CVS的开发环境 9.2.1 下载CVS 9.2.2 配置CVS 9.3 CVS的使用方法 ...
8.4.3 改变初始化和销毁方式 8.4.4 改变异常处理的方式 8.5 小结 第九章 CVS使用指南 9.1 CVS介绍 9.1.1 CVS简介 9.1.2 为什么要使用CVS 9.2 建立CVS的开发环境 9.2.1 下载CVS 9.2.2 配置CVS 9.3 CVS的使用方法 ...
6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用...
所有的请求都将被它拦截,并且在初始化该servlet的时候就将映射初始化进来,因此DispatchServlet可以返回映射之后的视图。 MyBatis MyBatis 是一个不错的持久层框架,减少了代码的硬编码,也支持用户自己编写SQL...
6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用...
java8 源码 Learn Spring Bean 注解 Target 关联注解 所在模块 所在包 ...事务(Transactional) ...MVC ...学习Spring的关键 ...注解就相当于在业务开发中的功能需求,重点是理解加上注解之后程序如何...容器初始化的工作。 sprin
8.4.3 改变初始化和销毁方式 8.4.4 改变异常处理的方式 8.5 小结 第九章 CVS使用指南 9.1 CVS介绍 9.1.1 CVS简介 9.1.2 为什么要使用CVS 9.2 建立CVS的开发环境 9.2.1 下载CVS 9.2.2 配置CVS 9.3 CVS的使用方法 ...
因为我们并没有指定哪一个范围的username,所以它会依序从Page、Request、Session、 Application范围查找。 假如途中找到username,就直接回传,不再继续找下去,但是假如全部的范围都没有找到时, 就回传null。 ...
Simple Weather源码 4.7. 添加资源 4.8. 运行Simple Weather项目 4.8.1. Maven Exec 插件 4.8.2. 浏览你的项目依赖 4.9. 编写单元测试 4.10. 添加测试范围依赖 4.11. 添加单元测试资源 4.12. 执行单元...