Java笔记Spring(四)
spring web项目启动入口
1、首先看一下传统Java Web的配置文件web.xml,网上找的一个,参考地址:https://blog.csdn.net/github_36301064/article/details/53290900
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"> <servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet> <servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet> <servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping> <servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping> <session-config>
<session-timeout>30</session-timeout>
</session-config> <!-- 这里省略了大概4000多行的MIME类型的定义,这里只给出两种MIME类型的定义 -->
<mime-mapping>
<extension>bmp</extension>
<mime-type>image/bmp</mime-type>
</mime-mapping>
<mime-mapping>
<extension>htm</extension>
<mime-type>text/html</mime-type>
</mime-mapping> <welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
2、看一下spring web项目中的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"> <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet2.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list> <filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
dispatcher对应的servlet下的init-param可以不设置,默认使用/WEB-INF/dispatcher-servlet.xml
3、Tomcat等web容器启动干了什么,参考:https://blog.csdn.net/lieyanhaipo/article/details/58605545
容器启动的时候会调用 listen-class 的初始化事件,即 org.springframework.web.context.ContextLoaderListener 的初始化方法会被调用,同时 org.springframework.web.context.ContextLoaderListener 必须实现javax.servlet.ServletContextListener(Servlet)接口,
public void contextInitialized(ServletContextEvent sce); 接口中的初始化方法会被调用
public class ContextLoaderListener extends ContextLoader implements ServletContextListener { public ContextLoaderListener() {
} public ContextLoaderListener(WebApplicationContext context) {
super(context);
} @Override
public void contextInitialized(ServletContextEvent event) {
initWebApplicationContext(event.getServletContext());
} @Override
public void contextDestroyed(ServletContextEvent event) {
closeWebApplicationContext(event.getServletContext());
ContextCleanupListener.cleanupAttributes(event.getServletContext());
} }
具体的实现在父类ContextLoader中
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
throw new IllegalStateException(
"Cannot initialize context because there is already a root application context present - " +
"check whether you have multiple ContextLoader* definitions in your web.xml!");
} Log logger = LogFactory.getLog(ContextLoader.class);
servletContext.log("Initializing Spring root WebApplicationContext");
if (logger.isInfoEnabled()) {
logger.info("Root WebApplicationContext: initialization started");// spring web启动日志
}
long startTime = System.currentTimeMillis(); try {
// Store context in local instance variable, to guarantee that
// it is available on ServletContext shutdown.
if (this.context == null) {
this.context = createWebApplicationContext(servletContext);// 创建WebApplicationContext,默认WebApplicationContext为XmlWebApplicationContext
}
if (this.context instanceof ConfigurableWebApplicationContext) {
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
if (!cwac.isActive()) {
// The context has not yet been refreshed -> provide services such as
// setting the parent context, setting the application context id, etc
if (cwac.getParent() == null) {
// The context instance was injected without an explicit parent ->
// determine parent for root web application context, if any.
ApplicationContext parent = loadParentContext(servletContext);
cwac.setParent(parent);
}
configureAndRefreshWebApplicationContext(cwac, servletContext);
}
}
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); ClassLoader ccl = Thread.currentThread().getContextClassLoader();
if (ccl == ContextLoader.class.getClassLoader()) {
currentContext = this.context;
}
else if (ccl != null) {
currentContextPerThread.put(ccl, this.context);
} if (logger.isDebugEnabled()) {
logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" +
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
}
if (logger.isInfoEnabled()) {
long elapsedTime = System.currentTimeMillis() - startTime;
logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");// spring web启动日志
} return this.context;
}
catch (RuntimeException ex) {
logger.error("Context initialization failed", ex);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
throw ex;
}
catch (Error err) {
logger.error("Context initialization failed", err);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
throw err;
}
}
创建上下文代码
protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
Class<?> contextClass = determineContextClass(sc);
if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
"] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
}
return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
} /**
* Return the WebApplicationContext implementation class to use, either the
* default XmlWebApplicationContext or a custom context class if specified.
* @param servletContext current servlet context
* @return the WebApplicationContext implementation class to use
* @see #CONTEXT_CLASS_PARAM
* @see org.springframework.web.context.support.XmlWebApplicationContext
*/
protected Class<?> determineContextClass(ServletContext servletContext) {
String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);// null
if (contextClassName != null) {
try {
return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());
}
catch (ClassNotFoundException ex) {
throw new ApplicationContextException(
"Failed to load custom context class [" + contextClassName + "]", ex);
}
}
else {
contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());
try {
return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
throw new ApplicationContextException(
"Failed to load default context class [" + contextClassName + "]", ex);
}
}
}
spring-web工程下,resource资源目录下
ContextLoader.properties
# Default WebApplicationContext implementation class for ContextLoader.
# Used as fallback when no explicit context implementation has been specified as context-param.
# Not meant to be customized by application developers. org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext
默认的WebApplicationContext为XmlWebApplicationContext
private static final String DEFAULT_STRATEGIES_PATH = "ContextLoader.properties"; private static final Properties defaultStrategies; static {
// Load default strategy implementations from properties file.
// This is currently strictly internal and not meant to be customized
// by application developers.
try {
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
throw new IllegalStateException("Could not load 'ContextLoader.properties': " + ex.getMessage());
}
}
到此为止,WebApplicationContext(XmlWebApplicationContext)创建完毕。
Java笔记Spring(四)的更多相关文章
- Java笔记Spring(七)
DispatcherServlet初始化,继续分析日志 主要部分: 23-May-2018 17:47:55.457 INFO [RMI TCP Connection(3)-127.0.0.1] or ...
- Java笔记Spring(五)
C:\apache-tomcat-8.0.36\bin\catalina.bat run [2018-05-23 02:30:31,657] Artifact demo-springmvc:war e ...
- Java笔记(四)常用基础类
常用基础类 一)String String内部用一个字符数组表示字符串: private final char value[]; 注意:Java9对此做了优化,采用byte[],如果字符都是ASCII ...
- Java笔记Spring(一)
一.Spring框架 源码地址:https://github.com/spring-projects/spring-framework 构建工具:Gradle,Gradle教程:https://www ...
- 菜鸡的Java笔记 第四 - java 基础运算符
数学运算符,逻辑运算,三目运算,位运算 double d2 = 314e2; //采用科学计数法的写法,表示10的2次方.= 31400.0 代码写的越简单越好 简化运算符 代码:x=x+y 可以 ...
- Effective java笔记(四),泛型
泛型为集合提供了编译时类型检查. 23.不要在代码中使用原生态类型 声明中具有一个或多个类型参数的类或接口统称为泛型.List<E>是一个参数化类,表示元素类型为E的列表.为了提供兼容性, ...
- Java笔记(十四)……抽象类与接口
抽象类概念 抽象定义: 抽象就是从多个事物中将共性的,本质的内容抽取出来. 例如:狼和狗共性都是犬科,犬科就是抽象出来的概念. 抽象类: Java中可以定义没有方法体的方法,该方法的具体实现由子类完成 ...
- Java笔记Spring(八)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- Java笔记Spring(六)
web.xml各节点加载顺序 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns=&q ...
随机推荐
- day19_python_1124
.01 昨日内容回顾 面向对象:1,将一些相似功能的函数集合到一起 类:具有相同属性和功能的一类事物. 对象:类的具体体现. 2,站在上帝的角度考虑问题,类就是一个公共模板, 类的结构: class ...
- day17_python_1124
01 昨日内容回顾 包: 1,在内存中创建一个以包命名的空间. 2,执行包的__init__文件将文件中的名字加载到包的名称空间. 3,通过包名.名字(变量,函数,类名)方式调用这些内容. aaa.x ...
- 201621123075《Java程序设计》第1周学习总结
1.本周学习总结 本周简单了解了一些Java的基本概念,如Java的用途,功能.也学习了一些变量,类型和运算符.我感觉学好Java也是不容易的,尽管它库函数丰富,可最重要的还是那一份创造力. 2.书面 ...
- Android : 关于HTTPS、TLS/SSL认证以及客户端证书导入方法
一.HTTPS 简介 HTTPS 全称 HTTP over TLS/SSL(TLS就是SSL的新版本3.1).TLS/SSL是在传输层上层的协议,应用层的下层,作为一个安全层而存在,翻译过来一般叫做传 ...
- 使用GraphHttpClient调用Microsoft Graph接口 - GET
博客地址:http://blog.csdn.net/FoxDave 使用GraphHttpClient类调用Microsoft Graph REST API,你可以使用GET,POST和PATCH请求 ...
- bfs两种记录路径方法
#include<cstdio> #include<queue> using namespace std; struct sss { int x,y; }ans[][]; ][ ...
- python安装pip管理工具
(1)安装python2.7.5,这里我选择安装在C盘根目录下. (2)安装完毕后C盘会生成一个叫“python27”的文件夹. (3)打开python27,会发现该目录下存在一个叫Scripts的文 ...
- guava-retrying 源码解析(时间限制策略)
一.时间限制策略相关接口和类 什么是时间限制策略呢?是指在一个时间限制内,包装任何一种重试(尝试)规则,如果超过该限制,那么这个尝试规则可能会被中断,并抛出UncheckedTimeoutExcept ...
- 黑客炼金术士 Seeker:可以攻破 4G 摸到你短信,还要为朝阳群众提供谍战工具
在北京上地的一家咖啡馆里,我在等待黑客 Seeker 的到来. 我对黑客 Seeker 颇有期待.他曾在黑客大会 KCon 上演讲<伪基站高级利用技术——彻底攻破短信验证码>,介绍利用 L ...
- 记一次ssh配置的锅
我们在使用git来管理代码的时候不可避免的要用到ssh密匙,这个密匙怎么配置的百度上很多. 我这边是使用sourcetree来配合管理代码的,但是我ssh配置好了以后无论是克隆代码还是推送代码都提示我 ...