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


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

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

    1、我们要实现无web.xml的配置,只需要关注实现WebApplicationInitializer这个接口,以下为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;
    
    }

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

    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");
        }
    }

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

    <?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>

    4、我们分类解读,在web.xml配置里面我们配置的Web Application Context

        <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中的

    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配置里面我们配置的log4j

    <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的

        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)

        <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");
        }

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

    5、如上面所说的,我们对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

     
    
    
    
    
    
    
    
    
    
    














  • 相关阅读:
    CSS实现雨滴动画效果
    大型网站架构系列:电商网站架构案例
    CSS 不定宽高的垂直水平居中方式总汇
    js中尺寸类样式
    Tiling
    排序二叉树
    算术表达式的转换
    Area
    catch that cow
    R中双表操作学习[转载]
  • 原文地址:https://www.cnblogs.com/softidea/p/6928479.html
Copyright © 2020-2023  润新知