上一章,我们学习了servlet3.0的基础特性,在servlet3.0中,最突出的特性就是注解式和编程式动态添加和配置设置。所以我们在查看Springmvc源码的时候,也是从这个地方入手。
我们现在很多项目,都是采用的注解方式,而取消掉了以前的配置文件,web.xml和application.xml,这些实现的方式其实就是使用了编程式添加配置。现在让我们一起来看一看,如何配置Springmvc
Springmvc 原理
源码分析
//根据我们之前分析的servlet3.0, 发现SpringWeb中的SpringServletContainerInitializer实现了
//ServletContainerInitializer 这个也就是Springmvc的入口
//WebApplicationInitializer 为所有初始化的接口, 实现了接口中的 onStartup方法
@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
@Override
public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
throws ServletException {
List<WebApplicationInitializer> initializers = new LinkedList<>();
if (webAppInitializerClasses != null) {
for (Class<?> waiClass : webAppInitializerClasses) {
// Be defensive: Some servlet containers provide us with invalid classes,
// no matter what @HandlesTypes says...
//获取到所有的WebApplicationInitializer实现,如果不是接口,不是抽象类
//并且是WebApplicationInitializer,则进行实例化放入 LinkedList initializers
if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
try {
initializers.add((WebApplicationInitializer)
ReflectionUtils.accessibleConstructor(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;
}
servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
AnnotationAwareOrderComparator.sort(initializers);
for (WebApplicationInitializer initializer : initializers) {
initializer.onStartup(servletContext);
}
}
}
WebApplicationInitializer 实现类
如何通过编程式使用Springmvc
根据之前的过程,我们需要一个 WebApplicationInitializer实现类,而通过上图我们知道,AbstractAnnotationConfigDispatcherServletInitializer 是最下面的抽象类,所以我们可以从AbstractAnnotationConfigDispatcherServletInitializer这个类入口,适配器模式
public class MySpringMvc extends AbstractAnnotationConfigDispatcherServletInitializer{
/**
* Specify {@code @Configuration} and/or {@code @Component} classes for the
* {@linkplain #createRootApplicationContext() root application context}.
*
* @return the configuration for the root application context, or {@code null} if creation and
* registration of a root context is not desired
*/
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
/**
* Specify {@code @Configuration} and/or {@code @Component} classes for the
* {@linkplain #createServletApplicationContext() Servlet application context}.
*
* @return the configuration for the Servlet application context, or {@code null} if all
* configuration is specified through root config classes.
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[0];
}
/**
* Specify the servlet mapping(s) for the {@code DispatcherServlet} —
* for example {@code "/"}, {@code "/app"}, etc.
*
* @see #registerDispatcherServlet(ServletContext)
*/
@Override
protected String[] getServletMappings() {
return new String[0];
}
}
以MySpringmvc 为基础 看看是如何调用的