究 Spring 3.1之无web.xml式 基于代码配置的servlet3.0应用
大家应该都已经知道Spring 3.1对无web.xml式基于代码配置的servlet3.0应用。通过spring的api或是网络上高手们的博文,也一定很快就学会并且加到自己的应用中去了。PS:如果还没,也可以小小参考一下鄙人的上一篇文章<<探 Spring 3.1之无web.xml式 基于代码配置的servlet3.0应用>>。
经过一天的深度research, 我了解,理解以及重现了springframework的那一小段代码。
OK,第一步,入手点,WebApplicationInitializer接口。因为我们只需实现这个接口覆写它的一个方法,就可以做到配置web.xml同样的功效。看它的源码,其实看和不看没什么两样:
package org.springframework.web;import javax.servlet.ServletContext;import javax.servlet.ServletException;public interface WebApplicationInitializer {void onStartup(ServletContext servletContext) throws ServletException;}
package org.springframework.web;import java.lang.reflect.Modifier;import java.util.Collections;import java.util.LinkedList;import java.util.List;import java.util.ServiceLoader;import java.util.Set;import javax.servlet.ServletContainerInitializer;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.annotation.HandlesTypes;import org.springframework.core.annotation.AnnotationAwareOrderComparator;@HandlesTypes(WebApplicationInitializer.class)public class SpringServletContainerInitializer implements ServletContainerInitializer {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;}Collections.sort(initializers, new AnnotationAwareOrderComparator());servletContext.log("Spring WebApplicationInitializers detected on classpath: " + initializers);for (WebApplicationInitializer initializer : initializers) {initializer.onStartup(servletContext);}}}
package com.gxino.imagecapture.cfg;import javax.servlet.ServletContext;import javax.servlet.ServletException;public interface WebParameter {public void loadInfo(ServletContext servletContext) throws ServletException;}
package com.gxino.imagecapture.cfg;import java.lang.reflect.Modifier;import java.util.Set;import javax.servlet.ServletContainerInitializer;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.annotation.HandlesTypes;@HandlesTypes(WebParameter.class)public class WebConfiguration implements ServletContainerInitializer {@Overridepublic void onStartup(Set<Class<?>> webParams, ServletContext servletCtx)throws ServletException {if (webParams != null) {for (Class<?> paramClass : webParams) {if (!paramClass.isInterface() && !Modifier.isAbstract(paramClass.getModifiers()) &&WebParameter.class.isAssignableFrom(paramClass)) {try {((WebParameter) paramClass.newInstance()).loadInfo(servletCtx);}catch (Throwable ex) {throw new ServletException("Failed to instantiate WebParam class", ex);}}}//loop}//Web Params}//onStartup}
package com.gxino.imagecapture.ctrl;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.gxino.imagecapture.cfg.WebParameter;public class TestServlet extends HttpServlet {public void doGet(HttpServletRequest req, HttpServletResponse resp){System.out.println("Some client access once");try {req.getRequestDispatcher("/index.jsp").forward(req, resp);} catch (ServletException | IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
package com.gxino.imagecapture.cfg;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRegistration;public class ServletParameter implements WebParameter {@Overridepublic void loadInfo(ServletContext servletContext) throws ServletException {ServletRegistration.Dynamic testServlet=servletContext.addServlet("test","com.gxino.imagecapture.ctrl.TestServlet");testServlet.setLoadOnStartup(1);testServlet.addMapping("/index.html");}}
package com.gxino.imagecapture.ctrl;import java.io.IOException;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRegistration;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.gxino.imagecapture.cfg.WebParameter;public class TestServlet extends HttpServlet implements WebParameter{@Overridepublic void loadInfo(ServletContext servletContext) throws ServletException {ServletRegistration.Dynamic testServlet=servletContext.addServlet("test", "com.gxino.imagecapture.ctrl.TestServlet");testServlet.setLoadOnStartup(1);testServlet.addMapping("/index.html");}public void doGet(HttpServletRequest req, HttpServletResponse resp){System.out.println("Some client access once");try {req.getRequestDispatcher("/index.jsp").forward(req, resp);} catch (ServletException | IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}