springmvc基于java config的实现

来源:互联网 发布:网络打印机ip地址设置 编辑:程序博客网 时间:2024/05/23 01:09
参考资料:servlet-3_1-final.pdf(servlet 3.1规范)8.2.4Shared libraries / runtimes pluggability
通过ServletContainerInitializer来实现可插拔性,至少需要servlet 3+.


1.以上的参考资料提到可以通过ServletContainerInitializer实现可插拔性.每个应用在启动时,容器都会创建一个ServletContainerInitializer实例.

2.框架提供在jar包的META-INF/service目录下的javax.servlet.ServletContainerInitializer文件内容就是指向ServletContainerInitializer实现类.
spring mvc提供的这个实现类叫做org.springframework.web.SpringServletContainerInitializer,这个jar的文件名是spring-web-X.X.X.X.jar.

3.这个实现类的HandlesTypes注解用在表示那些感兴趣的类,这些类或者它的超类是由HandlesTypes值指定的,HandlesTypes的应用与metadata-complete的设置无关.
spring mvc的HandlesTypes值只有WebApplicationInitializer.class一个,那么凡是在类路径上的WebApplicationInitializer子类都是感兴趣的类.它们将会传入onStartup方法的第一个参数.下面是org.springframework.web.SpringServletContainerInitializer#onStartup方法

public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)throws ServletException {List<WebApplicationInitializer> initializers = new LinkedList<WebApplicationInitializer>();if (webAppInitializerClasses != null) {for (Class<?> waiClass : webAppInitializerClasses) {// Be defensive: Some servlet containers provide us with invalid classes,// no matter what @HandlesTypes says...if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&WebApplicationInitializer.class.isAssignableFrom(waiClass)) {try {initializers.add((WebApplicationInitializer) waiClass.newInstance());}catch (Throwable ex) {throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);}}}}if (initializers.isEmpty()) {servletContext.log("No Spring WebApplicationInitializer types detected on classpath");return;}AnnotationAwareOrderComparator.sort(initializers);servletContext.log("Spring WebApplicationInitializers detected on classpath: " + initializers);for (WebApplicationInitializer initializer : initializers) {initializer.onStartup(servletContext);}}


从此方法可看出,在启动应用时,所有有效(这个有效的意思可以看上面的try外层的if)的Initializer都共用同一个ServletContext,一个一个去启动它的onStartup方法.如果要更改initializers顺序,应该可通过@Order注解(数值越低排序越前)或实现Ordered接口去实现.

基于java-config的spring mvc,我们一般都会继承AbstractAnnotationConfigDispatcherServletInitializer(它当然是WebApplicationInitializer的实现类)来写一个Initializer.这个Initializer最基本的就帮我们注册了DispatcherServlet.


如果容器不支持servlet3+(有些老古董思想,要绕一下路),那么就离不开web.xml,下面替代方案:

<?xml version="1.0" encoding="UTF-8"?><web-app 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"         version="2.5">    <display-name>web</display-name>    <!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext instead of the default XmlWebApplicationContext -->    <context-param>        <param-name>contextClass</param-name>        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>    </context-param>    <!-- Configuration locations must consist of one or more comma- or space-delimited         fully-qualified @Configuration classes. Fully-qualified packages may also be         specified for component-scanning -->    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>com.xxx.auth.web.config.AppConfig</param-value>    </context-param>    <!-- Bootstrap the root application context as usual using ContextLoaderListener -->    <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>    <filter>        <filter-name>charsetFilter</filter-name>        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>        <init-param>            <param-name>encoding</param-name>            <param-value>UTF-8</param-value>        </init-param>    </filter>    <filter-mapping>        <filter-name>charsetFilter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>    <servlet>        <servlet-name>dispatcher</servlet-name>        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        <!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext instead of the default XmlWebApplicationContext -->        <init-param>            <param-name>contextClass</param-name>            <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>        </init-param>        <!-- Again, config locations must consist of one or more comma- or space-delimited and fully-qualified @Configuration classes -->        <init-param>            <param-name>contextConfigLocation</param-name>            <param-value>com.xxx.auth.web.config.MvcConfig</param-value>        </init-param>        <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>        <servlet-name>dispatcher</servlet-name>        <url-pattern>/</url-pattern>    </servlet-mapping></web-app>


基于javaConfig的springMvc,不是不使用web.xml,而是可以不使用web.xml,应理解web.xml不是必须的(所以那些所谓的零配置,我认为是不准确的),比如session-config,jsp-config,mime-mapping,error-page还是要使用web.xml,可参考servlet-3_1-final.pdf



0 0
原创粉丝点击