纯代码配置 SSM 框架 (二)

纯代码配置 SSM 框架 (二)

入口说明

Web 应用最重要的配置文件就是 web.xml 配置,它是 web 项目启动时首先被容器读取的配置文件,根据其中的配置创建实例并完成参数初始化等以保证项目能够正确启动运行。在 Spring MVC 框架中,只要实现 WebApplicationInitializer 接口,并重写 void onStartup(ServletContext servletContext) throws ServletException; 方法,即可让 Servlet 3.0 容器自动引导。

下面是 WebApplicationInitializer 接口的源码,非常简单。

package org.springframework.web;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;

public interface WebApplicationInitializer {
    void onStartup(ServletContext var1) throws ServletException;
}

官方的接口说明如下

Interface to be implemented in Servlet 3.0+ environments in order to configure the ServletContext programmatically – as opposed to (or possibly in conjunction with) the traditional web.xml-based approach.

这个 SPI 的实现将被 SpringServletContainerInitializer 自动检测到,它本身是由任何 Servlet 3.0 容器自动引导的。

Implementations of this SPI will be detected automatically by SpringServletContainerInitializer, which itself is bootstrapped automatically by any Servlet 3.0 container.

实现该接口可以在 Servlet 3.0 + 环境中以编程方式配  ServletContext ,而不是(或结合)传统的基于 web.xml 文件配置。

配置

web.xml 中配置的项目主要有:上下文参数监听器过滤器。因为纯代码配置,上下文参数会直接在代码中配置中配置、过滤器将由DispatcherServlet配置,因此在该配置中,主要配置相关的监听器。

WebInitializer配置如下:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.web.WebApplicationInitializer;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;

@Order(1)
public class WebInitializer implements WebApplicationInitializer {
    private static final Logger logger = LoggerFactory.getLogger(WebInitializer.class);

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        logger.info("onStartup");
        Log4j2Config.config(servletContext);
        SpringConfig.config(servletContext);
        DruidConfig.config(servletContext);
    }
}

@Order(1) : 通过该注解、规定了 Spring 加载顺序。

因为项目使用了 Druid 数据缓冲池、 2.x版本Log4j 日志框架、和 Spring 相关监听器。

Log4j2Config 配置如下:

import javax.servlet.ServletContext;
import java.util.EnumSet;

import static javax.servlet.DispatcherType.*;

public final class Log4j2Config {
    public static void config(ServletContext servletContext) {
        servletContext.setInitParameter("isLog4jAutoInitializationDisabled", "true");
        servletContext.getFilterRegistration("log4jServletFilter")
                .addMappingForUrlPatterns(
                        EnumSet.of(REQUEST, FORWARD, INCLUDE, ERROR, ASYNC),
                        false,
                        "/*");
    }
}

SpringConfig 配置如下:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextListener;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.util.IntrospectorCleanupListener;

import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;

public final class SpringConfig {
    private static final Logger logger = LoggerFactory.getLogger(SpringConfig.class);

    private static final String ENCODING_FILTER = "encodingFilter";

    public static void config(ServletContext servletContext) {
        logger.debug("RequestContextListener:request作用域");
        servletContext.addListener(RequestContextListener.class);
        logger.debug("IntrospectorCleanupListener:主要负责处理由JavaBeansIntrospector的使用而引起的缓冲泄露");
        servletContext.addListener(IntrospectorCleanupListener.class);
        logger.info("Spring字符集过滤器");
        FilterRegistration.Dynamic dynamic = servletContext.addFilter(ENCODING_FILTER, CharacterEncodingFilter.class);
        Map<String, String> map = new HashMap<>();
        map.put("encoding", "UTF-8");
        map.put("forceEncoding", "true");
        dynamic.setInitParameters(map);
        dynamic.addMappingForUrlPatterns(EnumSet.of(
                DispatcherType.REQUEST,
                DispatcherType.FORWARD,
                DispatcherType.INCLUDE,
                DispatcherType.ERROR,
                DispatcherType.ASYNC),
                false,
                "/*");
    }
}

DruidConfig 配置如下:

import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;

public final class DruidConfig {
    private static final Logger logger = LoggerFactory.getLogger(DruidConfig.class);

    private static final String DRUID_WEB_STAT_FILTER = "DruidWebStatFilter";
    private static final String DRUID_STAT_VIEW_SERVLET = "DruidStatViewServlet";

    public static void config(ServletContext servletContext) {
        logger.info("配置阿里云监控");
        configDruidWebStatFilter(servletContext);
        configDruidStatView(servletContext);
    }

    private static void configDruidStatView(ServletContext servletContext) {
        logger.info("配置druid页面显示");
        ServletRegistration.Dynamic dynamic = servletContext.addServlet(DRUID_STAT_VIEW_SERVLET, StatViewServlet.class);
        Map<String, String> map = new HashMap<>();
        map.put("profileEnable", "true");
        map.put("resetEnable", "true");
        map.put("loginUsername", "账号");
        map.put("loginPassword", "密码");
        dynamic.setInitParameters(map);
        dynamic.addMapping("/druid/*");
    }

    private static void configDruidWebStatFilter(ServletContext servletContext) {
        logger.info("阿里数据源,连接池启用Web监控统计功能START");
        FilterRegistration.Dynamic dynamic = servletContext.addFilter(DRUID_WEB_STAT_FILTER, WebStatFilter.class);
        Map<String, String> map = new HashMap<>();
        map.put("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        dynamic.setInitParameters(map);
        dynamic.addMappingForUrlPatterns(EnumSet.of(
                DispatcherType.REQUEST,
                DispatcherType.FORWARD,
                DispatcherType.INCLUDE,
                DispatcherType.ERROR,
                DispatcherType.ASYNC),
                false,
                "/*");
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章