spring提供了一种基于注解方式来替换xml配置文件,那么springmvc也是支持的。下面来介绍一些类,来完成之前的基于xml配置的功能
一、运行机制
Servlet在启动的时候会查看当前类路径中是否有实现WebApplicationInitializer接口,如果实现了该接口则会调用onStartup方法,进行Servlet进行初始化
假设自定义一个类WebInit继承AbstractAnnotationConfigDispatcherServletInitializer类,执行流程图如下:
protected void registerDispatcherServlet(ServletContext servletContext) {
String servletName = getServletName(); // dispatcher
Assert.hasLength(servletName, "getServletName() must not return null or empty");
//创建ioc容器 接收
WebApplicationContext servletAppContext = createServletApplicationContext();
Assert.notNull(servletAppContext, "createServletApplicationContext() must not return null");
// 创建DispatcherServlet对象,用父类接收
FrameworkServlet dispatcherServlet = createDispatcherServlet(servletAppContext);
Assert.notNull(dispatcherServlet, "createDispatcherServlet(WebApplicationContext) must not return null");
dispatcherServlet.setContextInitializers(getServletApplicationContextInitializers());
//动态注册Servlet
ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, dispatcherServlet);
if (registration == null) {
throw new IllegalStateException("Failed to register servlet with name '" + servletName + "'. " +
"Check if there is another servlet registered under the same name.");
}
registration.setLoadOnStartup(1); //启动顺序
registration.addMapping(getServletMappings()); //servlet-mapping 映射器注册, 这个接口是由实现类提供
registration.setAsyncSupported(isAsyncSupported());
Filter[] filters = getServletFilters(); //注册过滤器, 这个接口是由实现类提供
if (!ObjectUtils.isEmpty(filters)) {
for (Filter filter : filters) {
registerServletFilter(servletContext, filter);
}
}
customizeRegistration(registration);
}
二、WebInit具体实现
这个实现类不需要任何注解进行标注,在启动时自动被加载
package com.example.config;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
/**
* SpringMvc web工程初始化类,用于替换web.xml文件
*/
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {
/**
* 指定spring的配置类
* @return
*/
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
/**
* 指定springmvc的配置类
* @return
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
/**
* 指定DispatchServlet的映射规则,即url-pattern
* @return
*/
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
/**
* 配置过滤器
* @return
*/
@Override
protected javax.servlet.Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceResponseEncoding(true);
HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();
FormContentFilter formContentFilter = new FormContentFilter();
return new Filter[]{characterEncodingFilter, methodFilter, formContentFilter};
}
}
二、SpringMvc配置类
用一个类来代表springmvc.xml配置文件,这个类需要用@Configuration进行标注
/**
* 代替springmvc.xml配置文件
* 1、组件扫描
* 2、视图解析器
* 3、视图控制器view-controller
* 4、注解驱动
* 5、拦截器
* 6、异常拦截器
* 7、上传下载
* 8、静态资源默认servlet
* 9、消息类型转换HttpMessageConvert
*/
@Configuration
//1、组件扫描
@ComponentScan("com.example.controller")
//4、注解驱动
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {
//2、视图解析器 参考官方 https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html
@Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setTemplateMode("HTML5");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine(SpringResourceTemplateResolver templateResolver) {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
return templateEngine;
}
@Bean
public ThymeleafViewResolver viewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine);
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setOrder(1);
return viewResolver;
}
//3、视图控制器view-controller
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
}
//* 5、拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
MyInterceptor interceptor = new MyInterceptor();
registry.addInterceptor(interceptor).addPathPatterns("/**").excludePathPatterns("/");
}
//* 6、异常拦截器
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();
Properties properties = new Properties();
properties.setProperty("java.lang.ArithmeticException", "error"); //指定exception和视图名字
exceptionResolver.setExceptionMappings(properties);
exceptionResolver.setExceptionAttribute("exceptionError");
resolvers.add(exceptionResolver);
}
//* 7、上传下载
@Bean
public MultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
return multipartResolver;
}
//* 8、静态资源默认servlet
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter messageConverter = new FastJsonHttpMessageConverter();
converters.add(messageConverter);
}
}
三、总结
这里介绍了一下注解版初始化流程以及通过类代替xml配置实现方式