JavaWeb项目在启动时执行特定操作

如何让springmvc在启动的时候执行特定的业务处理?

前言: java 的 web服务器启动时,经常会做一些特定的业务逻辑处理,比如数据库初始化,初始化系统参数,读取配置文库等.

实现方法

一.Web项目,Servlet非Spring

解决方案: 实现(ServletContextListener) 接口

1.定义类实现ServletContextListener接口,并定义自己要执行的业务逻辑

public class StartInit implements ServletContextListener {  
       static final Logger logger = LoggerFactory.getLogger(StartInit.class);  
       // 系统初始化执行方法  
       public void contextDestroyed(ServletContextEvent e) {  
           logger.info("系统停止...");  
       }  

       public void contextInitialized(ServletContextEvent e) {  
           logger.info("系统初始化开始...");  

           // 获取项目根目录  
           String root_path  = e.getServletContext().getRealPath("/");  
           logger.info("application path : {}",root_path);  

           // 初始化 ConfigFactorty  
           ConfigFactory.init(root_path);  
           // 初始化数据链接信息  
           DBManager.init();  
           // 初始化定时统计任务  
           TaskManager.init();  
           // 初始化用户信息查询位置  
           UserInfo.init();  
           // ... 
           logger.info("系统初始化结束...");  
       }  
}

2.将实现了ServletContextListener接口的类配置为( web.xml) listener

<?xml version="1.0" encoding="UTF-8"?>  
    <web-app version="3.0"   
        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">  
      <display-name>JMD Project</display-name>   
      <welcome-file-list>  
        <welcome-file>index.jsp</welcome-file>  
      </welcome-file-list>  
      <listener>  
        <listener-class>com.jmd.web.init.StartInit</listener-class>  
      </listener>  
      ...
      </web-app>

二.Web项目,使用Spring框架

解决方案: Spring-MVC的应用中,要实现类似的功能,主要是通过实现下面这些接口(任选一,至少一个即可)

1.ApplicationContextAware接口

    package org.springframework.context;

    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.Aware;
    import org.springframework.context.ApplicationContext;

    public interface ApplicationContextAware extends Aware {
        void setApplicationContext(ApplicationContext var1) throws BeansException;
    }

2.ServletContextAware 接口

    package org.springframework.web.context;

    import javax.servlet.ServletContext;
    import org.springframework.beans.factory.Aware;

    public interface ServletContextAware extends Aware {
        void setServletContext(ServletContext var1);
    }

3.InitializingBean 接口

    package org.springframework.beans.factory;

    public interface InitializingBean {
        void afterPropertiesSet() throws Exception;
    }

4.ApplicationListener 接口

    package org.springframework.context;

    import java.util.EventListener;
    import org.springframework.context.ApplicationEvent;

    public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
        void onApplicationEvent(E var1);
    }

示例代码:

package com.jmd.web.listener;

import org.apache.logging.log4j.*;
import org.springframework.beans.*;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.*;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ServletContextAware;
import javax.servlet.ServletContext;

@Component
public class StartupListener implements ApplicationContextAware, ServletContextAware,
        InitializingBean, ApplicationListener<ContextRefreshedEvent> {

    protected Logger logger = LogManager.getLogger();

    @Override
    public void setApplicationContext(ApplicationContext ctx) throws BeansException {
        logger.info("1 => StartupListener.setApplicationContext");
    }

    @Override
    public void setServletContext(ServletContext context) {
        logger.info("2 => StartupListener.setServletContext");
    }
    //在一个bean中使用@PostConstruct注解的方法会在setServletContext后执行,会在afterPropertiesSet前执行
    @Override
    public void afterPropertiesSet() throws Exception {
        logger.info("3 => StartupListener.afterPropertiesSet");
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent evt) {
        logger.info("4.1 => MyApplicationListener.onApplicationEvent");
        if (evt.getApplicationContext().getParent() == null) {
            logger.info("4.2 => MyApplicationListener.onApplicationEvent");
        }
    }

}

运行时,输出的顺序如下:

 1 => StartupListener.setApplicationContext
 2 => StartupListener.setServletContext
 3 => StartupListener.afterPropertiesSet
 4.1 => MyApplicationListener.onApplicationEvent
 4.2 => MyApplicationListener.onApplicationEvent
 4.1 => MyApplicationListener.onApplicationEvent

注意: onApplicationEvent方法会触发多次,初始化这种事情,越早越好,建议在setApplicationContext方法中处理。


 上一篇
Maven 私库的搭建 Maven 私库的搭建
前言: Maven私服(即Repository Manager)的主要作用: 方便内部人员发布内部使用的依赖; 方便存放官方仓库中没有的第三方依赖包; 减少从中央仓库下载的次数,节省带宽、提高maven build的效率; 减少对中央仓
2019-04-16
下一篇 
Intellij-Idea 好用的插件 Intellij-Idea 好用的插件
在使用Intellij-IDEA时发现的好用的插件一览JRebel request mapper //查找controller等路径映射方便 Eclipse Code Formatter 在idea中使用eclipse 格式化配置文件
  目录