1: 原始的Spring mvc 项目是要使用web.xml 来把DispatchServlet注入到Tomcat中。
2:Spring 3+后支持不使用xml配置,技术依赖Servlet3.0 SPI
- 新建Springmvc项目,引入依赖
```xml
org.springframework spring-webmvc 5.2.5.RELEASE
2. 添加启动配置类 AppConfig```java@Configuration@ComponentScan("com.mkb")public class AppConfig {}
添加内置tomcat
public class TomcatApplication {public static void run()throws Exception{/*** 这么启动tomcat不知道项目是web项目。所以不能执行MyWebApplicationInitializer 方法*/Tomcat tomcat = new Tomcat();tomcat.setPort(8080);tomcat.addWebapp("/", "D:\\workspace\\webapp");tomcat.start();tomcat.getServer().await();}}
启动主函数
public class MyWebApplicationInitializer implements WebApplicationInitializer {@Overridepublic void onStartup(ServletContext servletCxt) {System.out.println("start");// Load Spring web application configurationAnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();ac.register(AppConfig.class);ac.refresh(); //初始化Spring容器// Create and register the DispatcherServletDispatcherServlet servlet = new DispatcherServlet(ac);ServletRegistration.Dynamic registration = servletCxt.addServlet("app", servlet);registration.setLoadOnStartup(1);registration.addMapping("/*");}}
测试
@RestControllerpublic class IndexController {@RequestMapping("/test")public String index1(){return "1";}}
总结:Spring 3.0后支持0配置,为后期springboot的演变做了铺垫。
在Spring-web jar 下面, META-INF\services目录下会有一个javax.servlet.ServletContainerInitializer 类,按照SPI的规范,就是Tomcat的启动的时候 会加载这个目录下的这个配置。
@HandlesTypes({WebApplicationInitializer.class})public class SpringServletContainerInitializer implements ServletContainerInitializer {public SpringServletContainerInitializer() {}public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException {List<WebApplicationInitializer> initializers = new LinkedList();Iterator var4;if (webAppInitializerClasses != null) {var4 = webAppInitializerClasses.iterator();while(var4.hasNext()) {Class<?> waiClass = (Class)var4.next();if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(waiClass)) {try {initializers.add((WebApplicationInitializer)ReflectionUtils.accessibleConstructor(waiClass, new Class[0]).newInstance());} catch (Throwable var7) {throw new ServletException("Failed to instantiate WebApplicationInitializer class", var7);}}}}if (initializers.isEmpty()) {servletContext.log("No Spring WebApplicationInitializer types detected on classpath");} else {servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");AnnotationAwareOrderComparator.sort(initializers);var4 = initializers.iterator();while(var4.hasNext()) {WebApplicationInitializer initializer = (WebApplicationInitializer)var4.next();initializer.onStartup(servletContext);}}}}
@HandlesTypes({WebApplicationInitializer.class})
就是说,凡是实现 WebApplicationInitializer 接口的类 都会被执行,我们的项目中 MyWebApplicationInitializer 实现了 WebApplicationInitializer 接口,所以在Tomcat启动的时候会加载MyWebApplicationInitializer,这个方法中,实现了Spring容器的初始化,和DispatcherServlet 的初始化。
