在过去搭建spring + springMCV ,首先第一步要做的是什么 ,就是要配置web.xml 文件 ,把springMVC 中的Servlet 加载到tomcat 。通过加载 dispatcher 来启动整个spring容器。web.xml 如下 。
在Servlet 进入在3.0+时代后,Servlet 变支持了注解配置Servlet,而spring也推荐 java 代码的配置 。那么以上web.xml 配置Servlet,便可以通过实现WebApplicationInitializer 接口,来完成Servlet的配置 ,直接看代码,如下
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class WebInitializer implements WebApplicationInitializer {// 1 实现接口
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(MyMvcConfig.class); //注册自己的配置文件
ctx.setServletContext(servletContext); // 2 把 ServletContext 注入到spring容器中
Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx)); // 3 加载 dispatcher Servlet。
servlet.addMapping("/");
servlet.setLoadOnStartup(1);
}
}
MyMvcConfig 为自己的配置java文件 。,这里做简单的为容器注入了试图解析器。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@Configuration // 配置文件的支持
@EnableWebMvc // 开启springMCV
@ComponentScan("xxx") //扫描加载java文件
public class MyMvcConfig {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/classes/views/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
return viewResolver;
}
}
ok 其实这样配置,部署到tomcat中 ,运行,就会启动 WebInitializer.onStartup 来启动spring中的各种组件 。
在第一次接触到的时候还是和困惑?这个tomcat 是怎么时候,怎么来运行 WebInitializer.onStartup这个方法的呢。?一跟踪代码方法spring两个jar包中有这个代码的引用 ,一个是支持jetty的一个,web jar包 ,
如下图,这里就只跟踪下web中的代码 ,对jetty就不研究了
点进 SpringServletContainerInitializer 这个类,发现这个类 继承实现了 ServletContainerInitializer 这个接口 ,路径:javax.servlet.ServletContainerInitializer 。这个类可不是spring中的东西了 。完整代码 :
package org.springframework.web;
import java.lang.reflect.Modifier;
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 {
@Override
public void onStartup(Set
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);
}
}
}
注意标记黄色部分,一看原来不就是,把所有 WebApplicationInitializer 遍历了一遍,然后调用了 onStartup 方法把 servletContext传进去吗。 而我们开始写的 WebInitializer就属于
WebApplicationInitializer ,所以我们的WebInitializer从这里开始运行。那么 ServletContainerInitializer 又 是怎么加载的? 这个就要跟tomcat那边的代码了,我猜,也是拿到 所有 ServletContainerInitializer 的实现类,运行了 onStartup方法 。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章