spring学习(十一)--web.xml零配置启动spring框架

在开始之前,我们需要注意一下,要基于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

个人理解,如有错误,欢迎指正!
原文地址:https://www.cnblogs.com/gllegolas/p/11758592.html