在一个网站启动、结束时,咱们常常有些操做是须要执行的。 java
熟悉Asp.net的朋友,使用Global.asax很容易就搞定,在其中有Application_Start和Application_End等方法能够供咱们来轻松实现。 web
可是,在Java的SpringMVC框架中,须要如何实现这个功能呢?在互联网上,有很多相似文章,介绍功能的实现,我看过不少篇文档,基本都在一些关键点有所缺失,不少新手朋友照作每每达不到效果,下面我来阐述一下我正在使用的方法。 spring
原理:使用注解@PostConstruct和@PreDestroy来实现功能。 spring-mvc 从Java EE 5规范开始,Servlet中增长了两个影响Servlet生命周期的注解(Annotion);@PostConstruct和@PreDestroy。这两个注解被用来修饰一个非静态的void()方法 。写法有以下两种方式: 服务器 @PostConstruct mvc public void applicationStart(){ app System.out.println("application start"); 框架 } 函数
public @PostConstruct void applicationStart(){ 测试 System.out.println("application start"); } 被@PostConstruct修饰的方法会在服务器加载Servle的时候运行,而且只会被服务器执行一次。PostConstruct在构造函数以后执行,init()方法以前执行。执行生命周期以下: |
下边直接来看程序中怎么写吧,下图是我用来测试的项目结构,标红的3个是这个功能须要涉及的文件。
其中,web.xml用来配置Spring的servlet,内容以下:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>InskyScheduleCenter</display-name>
<!-- Spring应用上下文, 理解层次化的ApplicationContext --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/config/spring/applicationContext*.xml</param-value> </context-param>
<!-- DispatcherServlet, Spring MVC的核心 --> <servlet> <servlet-name>InskyScheduleCenter</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- DispatcherServlet对应的上下文配置, 默认为/WEB-INF/$servlet-name$-servlet.xml --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/config/spring/ScheduleCenter-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>InskyScheduleCenter</servlet-name> <!-- mvc-dispatcher拦截全部的请求 --> <url-pattern>/</url-pattern> </servlet-mapping>
</web-app> |
这个文件没啥说的,只是标明contextConfigLocation的位置。
再看ScheduleCenter-servlet.xml文件。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 本配置文件为InskyScheduleCenter项目提供其相关的Spring MVC配置 -->
<!-- 启用Spring基于annotation的DI, 使用户能够在Spring MVC中使用Spring的强大功能。 激活 @Required @Autowired,JSR 250's @PostConstruct, @PreDestroy and @Resource 等标注 --> <context:annotation-config />
<!-- 扫描自动加载的包名 --> <context:component-scan base-package="com.insky.InskyScheduleCenter.web"> </context:component-scan>
</beans> |
其中,<context:annotation-config />必定要加上,这样才能够激活对@PostConstruct和@PreDestroy等注解。自动扫描的包名也要写对,确保咱们的功能类global.java在配置的包名下。
最后看global.java文件。
package com.insky.InskyScheduleCenter.web.util;
import javax.annotation.PostConstruct; import javax.annotation.PreDestroy;
import org.springframework.stereotype.Service;
/** * * web应用的全局事件 * @author Simon * */ @Service public class global {
/** * 在web启动时执行 */ @PostConstruct public void applicationStart(){ System.out.println("application start"); }
/** * 在web结束时执行 */ @PreDestroy public void applicationEnd(){ System.out.println("InskyScheduleCenter application end");
} } |
咱们看到,这个类位于配置的被扫描包名com.insky.InskyScheduleCenter.web之下。
其中,在applicationStart和applicationEnd方法之上,存在注解@PostConstruct和@PreDestroy,当网站启动时,自动扫描到这两个注解时,在相应的生命周期,就会执行被注解的方法。
注意global.java的class顶部被标红的注解@Service,在不少文章中,其贴出的代码上没有这个注解,不少照作的新手朋友最终没有加上,运行的时候就没有效果了,最终会多花不少时间去找问题。
由于配置文件中的<context:component-scan base-package="com.insky.InskyScheduleCenter.web"></context:component-scan>只有扫描到有@Component @Controller@Service等这些注解的类,才会把这些类注册为bean,只有被注册为bean,才会加载到web容器的生命周期。
固然,实现这个功能还有不少其它的方式,如实现ApplicationListener接口等,我将会在将来的文章中阐述其它们。