Spring MVC让Web容器启动时自动执行代码
2016-04-12 16:53
274 查看
在web.xml中,对于每一个servlet都有一个load-on-startup属性,其值为一个整数。若该值为0或正整数,则当Web容器启动时,该servlet会自动加载,并调用其中的init()方法,整数值越小,加载的优先级越高;若值为负数或未指定,则该servlet只有被选择时才会被加载。
因此,可以考虑通过Servlet进行实现。并配置web.xml文件,令应用容器在启动时就自动加载一个servlet并执行其中的init()方法。servlet程序如下:
对应web.xml配置如下,这里优先级设为10:
这样即可实现servlet的自动加载。那么如果在项目中使用了Spring MVC框架,并且在初始化时需要整合Spring,或是需要用到在Spring中配置好的bean以及Spring MVC的controller,该如何处理呢?
我们知道,Spring通过ApplicationContext(通常翻译成上下文)来对bean进行配置与管理,因此若要与Spring整合,使用Spring的bean,必须先拿到相关的上下文,然后通过上下文获取bean。大致思路如下:
在Spring MVC中,这个ApplicationContext叫做WebApplicationContext,它直接继承于ApplicationContext。Spring MVC的WebApplicationContext分为两种,一种是Spring创建的一个全局WebApplicationContext上下文,称为根上下文,注意这个上下文是Spring的,不是Spring
MVC的,因此不包含Spring MVC的信息(如Spring MVC的controller等)。若在web.xml中配置了context-param,则其对应的xml对应的配置为根上下文。该上下文保存在ServletContext中(也叫application,Servlet的一个键值对空间,类似于session,但是与session的区别是ServletContext由所有客户端共用,而session只属于一个客户端)的一个键中,该键的名字为WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE属性的值,可以通过很多方法取出,下面会详述。另一种是Spring
MVC的DispatcherServlet(Spring MVC的Servlet,可以拥有多个)加载后自己的上下文,除了拥有根上下文的所有内容,还有Spring MVC的信息。这样的上下文同样保存在ServletContext中,key为"org.springframework.web.servlet.FrameworkServlet.CONTEXT."+servlet名称。
知道了上下文存在哪里,我们的思路也就明朗了。只要拿到这个ServletContext,就可以通过key得到对应的上下文,继而得到bean。
考虑如下web.xml配置:
从上述代码的第19行可以看出,在该工程下只有一个Spring MVC DispatcherServlet,其名称为appServlet,那么我们就可以确定Spring MVC的上下文保存在org.springframework.web.servlet.FrameworkServlet.CONTEXT.appServlet中。获取方法如下:
而对于Spring的根上下文,bean的获取方式就有很多种了。通过根上下文,也可以拿到ServletContext相关信息。
最终代码:
因此,可以考虑通过Servlet进行实现。并配置web.xml文件,令应用容器在启动时就自动加载一个servlet并执行其中的init()方法。servlet程序如下:
package com.xxx.action; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; public class AutoRunServlet extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; public void init() throws ServletException { System.out.println("Servlet has been initialized!"); } }
对应web.xml配置如下,这里优先级设为10:
<servlet> <servlet-name>autoRunServlet</servlet-name> <servlet-class>com.xxx.action.AutoRunServlet</servlet-class> <load-on-startup>10</load-on-startup> </servlet>
这样即可实现servlet的自动加载。那么如果在项目中使用了Spring MVC框架,并且在初始化时需要整合Spring,或是需要用到在Spring中配置好的bean以及Spring MVC的controller,该如何处理呢?
我们知道,Spring通过ApplicationContext(通常翻译成上下文)来对bean进行配置与管理,因此若要与Spring整合,使用Spring的bean,必须先拿到相关的上下文,然后通过上下文获取bean。大致思路如下:
ApplicationContext ac = ... //获取ApplicationContext ExampleBean bean = (ExampleBean)ac.getBean(ExampleBean.class);//假设要获取的bean类型为ExampleBean
在Spring MVC中,这个ApplicationContext叫做WebApplicationContext,它直接继承于ApplicationContext。Spring MVC的WebApplicationContext分为两种,一种是Spring创建的一个全局WebApplicationContext上下文,称为根上下文,注意这个上下文是Spring的,不是Spring
MVC的,因此不包含Spring MVC的信息(如Spring MVC的controller等)。若在web.xml中配置了context-param,则其对应的xml对应的配置为根上下文。该上下文保存在ServletContext中(也叫application,Servlet的一个键值对空间,类似于session,但是与session的区别是ServletContext由所有客户端共用,而session只属于一个客户端)的一个键中,该键的名字为WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE属性的值,可以通过很多方法取出,下面会详述。另一种是Spring
MVC的DispatcherServlet(Spring MVC的Servlet,可以拥有多个)加载后自己的上下文,除了拥有根上下文的所有内容,还有Spring MVC的信息。这样的上下文同样保存在ServletContext中,key为"org.springframework.web.servlet.FrameworkServlet.CONTEXT."+servlet名称。
知道了上下文存在哪里,我们的思路也就明朗了。只要拿到这个ServletContext,就可以通过key得到对应的上下文,继而得到bean。
考虑如下web.xml配置:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- The definition of the Root Spring Container shared by all Servlets and Filters --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:service-context.xml</param-value> </context-param> <!-- Creates the Spring Container shared by all Servlets and Filters --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Processes application requests --> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>appServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
从上述代码的第19行可以看出,在该工程下只有一个Spring MVC DispatcherServlet,其名称为appServlet,那么我们就可以确定Spring MVC的上下文保存在org.springframework.web.servlet.FrameworkServlet.CONTEXT.appServlet中。获取方法如下:
ServletContext sc = getServletContext(); WebApplicationContext wac = (WebApplicationContext)sc.getAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.appServlet"); ExampleSpringMVCBean bean = ac.getBean(ExampleSpringMVCBean.class);
而对于Spring的根上下文,bean的获取方式就有很多种了。通过根上下文,也可以拿到ServletContext相关信息。
ServletContext sc = getServletContext(); WebApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(sc); ExampleBean bean = (ExampleBean)ac.getBean(ExampleBean.class);
ServletContext sc = getServletContext(); WebApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(sc); ExampleBean bean = (ExampleBean)ac.getBean(ExampleBean.class);//假设要获取的bean类型为ExampleBean
WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext(); ExampleBean bean = (ExampleBean)ac.getBean(ExampleBean.class);
ServletContext sc = getServletContext(); WebApplicationContext wac = (WebApplicationContext)sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); ExampleBean bean = (ExampleBean)ac.getBean(ExampleBean.class);
最终代码:
public class AutoRunServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
public void init() throws ServletException {
ServletContext sc = getServletContext(); WebApplicationContext wac = (WebApplicationContext)sc.getAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.appServlet"); ExampleSpringMVCBean bean = ac.getBean(ExampleSpringMVCBean.class);
WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext(); ExampleBean bean = (ExampleBean)ac.getBean(ExampleBean.class);
}
}
相关文章推荐
- Java 多线程处理任务的封装
- java 学习总结(二) 类的接口、继承与多态
- Struts2 入门学习笔记(一)——基本配置
- LeetCode(java)9. Palindrome Number
- Java 实现线程死锁
- 一张图读懂Java多线程
- java 中JDK安装与环境变量配置
- 开发当中日期格式的转换(java语言)
- 远程访问对象java实现
- Java基础之JavaBean
- java中的栈与堆
- eclipse jrebel插件
- 毕向东 Java学习 笔记一
- LeetCode(java)8. String to Integer (atoi)
- jdk7 api
- 新版eclipse中NDK环境搭建(免Cygwin,超级快)
- android(NDK+JNI)---Eclipse+CDT+gdb调试android ndk程序
- SpringMVC中添加Velocity的配置
- Java 设计模式--策略模式
- Java 多线程同步的五种方法