SpringMVC java 配置 DispatcherServlet

本文介绍如何利用Spring提供的SpringServletContainerInitializer类和AbstractAnnotationConfigDispatcherServletInitializer来简化Spring MVC的配置过程,避免在web.xml中进行繁琐的配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

springMVC是通过DispatcherServlet将请求的URL映射到对应的控制器方法上,传统的配置DispatcherServlet的方式是配置在web.xml文件中。但是在servlet3.0的环境中,servlet容器会在类路径中查找javax.servlet.ServletContainerInitializer接口的类,如果能发现,就会用来配置servlet容器。Spring提供了这个接口的实现名为SpringServletContainerInitializer

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<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;
}

AnnotationAwareOrderComparator.sort(initializers);
servletContext.log("Spring WebApplicationInitializers detected on classpath: " + initializers);

for (WebApplicationInitializer initializer : initializers) {
initializer.onStartup(servletContext);
}
}

}

这个类会查找实现WebApplicationInitializer的类并将容器配置任务交给它们。

AbstractAnnotationConfigDispatcherServletInitializer继承的父类
实现WebApplicationInitializer,在spring3.2版本以后。

[img]http://dl2.iteye.com/upload/attachment/0117/3512/27e2efcc-f10a-36bc-b256-da3175b27134.png[/img]


import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;


public class MyWebAppInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer{

@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] {RootConfig.class};
}

@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] {WebConfig.class};
}

@Override
protected String[] getServletMappings() {
return new String[] {"/"}; //将DispatcherServlet映射到"/"
}

}



因此我们只要继承AbstractAnnotationConfigDispatcherServletInitializer重写它的三个方法就可以配置DispatcherServlet和Spring应用上下文,而不需要在web.xml中配置。
getRootConfigClasses()方法返回带有@Configuration注解类会用来配置ContextLoaderListener创建应用上下文的Bean。getServletConfigClasses返回带有@Configuration注解的类会用来创建DispatcherServlet上下文中的bean,这两个上下文是父子关系。

下面我们看一下RootConfig和WebConfig


import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.PropertySource;

@ImportResource({"classpath:applicationContext.xml"})
//为了注入Environment,需要在RootConfig时加载配置文件
@PropertySource(value="classpath:application.properties")
@ComponentScan(basePackages={"com.asclepius.slhdt.serv"},excludeFilters ={ @Filter(type = FilterType.ASPECTJ, pattern = "com.asclepius.slhdt.serv.modules.*.controller.*Controller"), //排除所有控制器
@Filter(type = FilterType.REGEX, pattern = "com.asclepius.slhdt.serv.config.*")})
public class RootConfig {


}





@EnableWebMvc
@ComponentScan("com.asclepius.slhdt.serv.modules.*.controller")
public class WebConfig extends WebMvcConfigurerAdapter {


// Thymeleaf view Resolver
@Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver viewResolver =
new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine);
viewResolver.setCharacterEncoding("UTF-8");
return viewResolver;
}


// Template resolver
@Bean
public TemplateResolver templateResolver() {
TemplateResolver templateResolver =
new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setOrder(1);
return templateResolver;
}


public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
// 静态资源可访问
configurer.enable();
}

}



webconfig继承了WebMvcConfigurerAdapter 重写了configureDefaultServletHandling()方法,是为了使对静态资源的请求转发到servlet容器上,而不是控制器。注意webconfig与rootconfig扫描装备的bean不应该有重复,否则会产生两个同类的bean。webconfig只要扫描装配控制器,视图解析器等相关的bean,让dispatcherServlet映射,rootconfig则要扫描装配一般的bean。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值