Spring Web工程web.xml零配置即便用Java Config + Annotation

摘要: 在Spring 3.0以前,咱们工程中经常使用Bean都是经过XML形式的文件注解的,少了还能够,可是数量多,关系复杂到后期就很难维护了,因此在3.x以后Spring官方推荐使用Java Config方式去替换之前冗余的XML格式文件的配置方式;

java

在开始以前,咱们须要注意一下,要基于Java Config实现无web.xml的配置,咱们的工程的Servlet必须是3.0及其以上的版本;web

一、咱们要实现无web.xml的配置,只须要关注实现WebApplicationInitializer这个接口,如下为Spring源码:spring

public interface WebApplicationInitializer {

    /**
     * Configure the given {@link ServletContext} with any servlets, filters, listeners
     * context-params and attributes necessary for initializing this web application. See
     * examples {@linkplain WebApplicationInitializer above}.
     * @param servletContext the {@code ServletContext} to initialize
     * @throws ServletException if any call against the given {@code ServletContext}
     * throws a {@code ServletException}
     */
    void onStartup(ServletContext servletContext) throws ServletException;

}

 

二、咱们这里先不讲他的原理,只要咱们工程中实现这个接口的类,Spring容器在启动时候就会监听到咱们所实现的这个类,从而读取咱们的配置,就如读取web.xml同样,咱们的实现类以下所示:mvc

public class WebProjectConfigInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {

        initializeSpringConfig(container);

        initializeLog4jConfig(container);

        initializeSpringMVCConfig(container);

        registerServlet(container);

        registerListener(container);

        registerFilter(container);
    }

    private void initializeSpringConfig(ServletContext container) {
        // Create the 'root' Spring application context
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(AppConfiguration.class);
        // Manage the life cycle of the root application context
        container.addListener(new ContextLoaderListener(rootContext));
    }

    private void initializeSpringMVCConfig(ServletContext container) {
        // Create the spring rest servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
        dispatcherContext.register(RestServiceConfiguration.class);

        // Register and map the spring rest servlet
        ServletRegistration.Dynamic dispatcher = container.addServlet("SpringMvc",
                new DispatcherServlet(dispatcherContext));
        dispatcher.setLoadOnStartup(2);
        dispatcher.setAsyncSupported(true);
        dispatcher.addMapping("/springmvc/*");
    }

    private void initializeLog4jConfig(ServletContext container) {
        // Log4jConfigListener
        container.setInitParameter("log4jConfigLocation", "file:${rdm.home}/log4j.properties");
        container.addListener(Log4jConfigListener.class);
        PropertyConfigurator.configureAndWatch(System.getProperty("rdm.home") + "/log4j.properties", 60);
    }

    private void registerServlet(ServletContext container) {

        initializeStaggingServlet(container);
    }

    private void registerFilter(ServletContext container) {
        initializeSAMLFilter(container);
    }

    private void registerListener(ServletContext container) {
        container.addListener(RequestContextListener.class);
    }

    private void initializeSAMLFilter(ServletContext container) {
        FilterRegistration.Dynamic filterRegistration = container.addFilter("SAMLFilter", DelegatingFilterProxy.class);
        filterRegistration.addMappingForUrlPatterns(null, false, "/*");
        filterRegistration.setAsyncSupported(true);
    }

    private void initializeStaggingServlet(ServletContext container) {
        StaggingServlet staggingServlet = new StaggingServlet();
        ServletRegistration.Dynamic dynamic = container.addServlet("staggingServlet", staggingServlet);
        dynamic.setLoadOnStartup(3);
        dynamic.addMapping("*.stagging");
    }
}

三、以上的Java Config等同于以下web.xml配置:app

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <context-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
    </context-param>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.g360.configuration.AppConfiguration</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
     <context-param> 
        <param-name>log4jConfigLocation</param-name> 
        <param-value>file:${rdm.home}/log4j.properties</param-value> 
    </context-param> 
     <listener> 
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> 
    </listener> 

    <servlet>
        <description>staggingServlet</description>
        <display-name>staggingServlet</display-name>
        <servlet-name>staggingServlet</servlet-name>
        <servlet-class>com.g360.bean.interfaces.StaggingServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>staggingServlet</servlet-name>
        <url-pattern>*.stagging</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>SpringMvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextClass</param-name>
            <param-value>
                org.springframework.web.context.support.AnnotationConfigWebApplicationContext
            </param-value>
        </init-param>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>com.g360.configuration.RestServiceConfiguration</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringMvc</servlet-name>
        <url-pattern>/springmvc/*</url-pattern>
    </servlet-mapping>
    <filter> 
        <filter-name>SAMLFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <async-supported>true</async-supported>
     </filter> 
    <filter-mapping> 
    <filter-name>SAMLFilter</filter-name> 
        <url-pattern>/*</url-pattern> 
    </filter-mapping> 
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>
</web-app>

四、咱们分类解读,在web.xml配置里面咱们配置的Web Application Contextless

    <context-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
    </context-param>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.g360.configuration.AppConfiguration</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

就等价于Java Config中的jsp

private void initializeSpringConfig(ServletContext container) {
        // Create the 'root' Spring application context
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(AppConfiguration.class);
        // Manage the life cycle of the root application context
        container.addListener(new ContextLoaderListener(rootContext));
}

如此推断,在web.xml配置里面咱们配置的log4jasync

<context-param> 
        <param-name>log4jConfigLocation</param-name> 
        <param-value>file:${rdm.home}/log4j.properties</param-value> 
</context-param> 
<listener> 
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> 
</listener> 

就等价于Java Config的ide

    private void initializeLog4jConfig(ServletContext container) {
        // Log4jConfigListener
        container.setInitParameter("log4jConfigLocation", "file:${rdm.home}/log4j.properties");
        container.addListener(Log4jConfigListener.class);
        PropertyConfigurator.configureAndWatch(System.getProperty("rdm.home") + "/log4j.properties", 60);
    }

类此,在web.xml配置里面咱们配置的Spring Web(Spring Restful)this

    <servlet>
        <servlet-name>SpringMvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextClass</param-name>
            <param-value>
                org.springframework.web.context.support.AnnotationConfigWebApplicationContext
            </param-value>
        </init-param>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>com.g360.configuration.RestServiceConfiguration</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringMvc</servlet-name>
        <url-pattern>/springmvc/*</url-pattern>
    </servlet-mapping>

就等价于Java Config中的

private void initializeSpringMVCConfig(ServletContext container) {
        // Create the spring rest servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
        dispatcherContext.register(RestServiceConfiguration.class);

        // Register and map the spring rest servlet
        ServletRegistration.Dynamic dispatcher = container.addServlet("SpringMvc",
                new DispatcherServlet(dispatcherContext));
        dispatcher.setLoadOnStartup(2);
        dispatcher.setAsyncSupported(true);
        dispatcher.addMapping("/springmvc/*");
}

再此,在web.xml配置里面咱们配置的servlet

    <servlet>
        <description>staggingServlet</description>
        <display-name>staggingServlet</display-name>
        <servlet-name>staggingServlet</servlet-name>
        <servlet-class>com.g360.bean.interfaces.StaggingServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>staggingServlet</servlet-name>
        <url-pattern>*.stagging</url-pattern>
    </servlet-mapping>

就等价于Java Config中的

    private void initializeStaggingServlet(ServletContext container) {
        StaggingServlet staggingServlet = new StaggingServlet();
        ServletRegistration.Dynamic dynamic = container.addServlet("staggingServlet", staggingServlet);
        dynamic.setLoadOnStartup(3);
        dynamic.addMapping("*.stagging");
    }

后面以此类推,在这里不加详述了;

五、如上面所说的,咱们对Web 工程的总体配置都依赖于AppConfiguration这个配置类,下面是使用@Configuration 配置类注解的,你们使用过的,以此类推,都比较清楚,

这里就不加赘述了;

@Configuration
@EnableTransactionManagement
@EnableAsync
@EnableAspectJAutoProxy
@EnableScheduling
@Import({ RestServiceConfiguration.class, BatchConfiguration.class, DatabaseConfiguration.class, ScheduleConfiguration.class})
@ComponentScan({ "com.service", "com.dao", "com.other"})
public class AppConfiguration
{

  private Logger logger = LoggerFactory.getLogger(AppConfiguration.class);

  /**
   * 
   */
  public AppConfiguration ()
  {
    // TODO Auto-generated constructor stub
    logger.info("[Initialize application]");
    Locale.setDefault(Locale.US);
  }

}

还有就是对Spring Web配置的类RestServiceConfiguration ,我的可根据本身的实际项目需求在此配置本身的视图类型以及类型转换等等

@Configuration
@EnableWebMvc
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ComponentScan(basePackages = { "com.bean" })
public class RestServiceConfiguration extends WebMvcConfigurationSupport {
    
    @Bean
    public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
        RequestMappingHandlerAdapter handlerAdapter = super.requestMappingHandlerAdapter();
        return handlerAdapter;
    }

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        return new LocaleChangeInterceptor();
    }

    @Bean
    public LogAspect logAspect() {
        return new LogAspect();
    }
}

至此,咱们的 web.xml使用Java Config零配置就完了https://my.oschina.net/521cy/blog/702864

相关文章
相关标签/搜索