替代了原来的Servlet

-
- <dependency>
- <groupId>javax.servletgroupId>
- <artifactId>javax.servlet-apiartifactId>
- <version>4.0.1version>
- <scope>providedscope>
- dependency>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-webmvcartifactId>
- <version>${spring.version}version>
- dependency>
- @Controller
- public class UserController {
- @RequestMapping("/save")
- @ResponseBody
- public String save(){
- System.out.println("user save...");
- return "{'info':'SpringMVC'}";
- }
- }
- @Configuration
- @ComponentScan("com.example.controller")
- public class SpringMVCConfig {
- }
- public class ServletConfig extends AbstractDispatcherServletInitializer {
- @Override
- //加载SpringMVC的容器
- protected WebApplicationContext createServletApplicationContext() {
- AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
- context.register(SpringMVCConfig.class);
- return context;
- }
-
- @Override
- //设置哪些请求归属于SpringMVC处理
- protected String[] getServletMappings() {
- return new String[]{"/"};
- }
-
- @Override
- //加载Spring容器配置 SpringMVC底层会用到Spring
- protected WebApplicationContext createRootApplicationContext() {
- return null;
- }
- }
启动Tomcat服务器,访问/save路径



我的目录结构

Spring需要加载除controller外的所有包,SpringMVC需要加载controller包
SpringMVCConfig

SpringConfig


这里会出现的一个问题是,由于SpringMVCConfig也用@Configuration注解,尽管SpringConfig已经把Controller排除了,但是SpringConfig 在扫描com.example包时 会调用SpringMVCConfig(里面加载了Controller) 把Controller重新加载回来,这样调用Spring的上下文对象仍然能得到Controller的实例化对象。测试代码和结果如下:

解决方法:
1.把这两个config都移到com.example包的外面,这样他们两个就不会被重复加载了。
2.SpringConfig加载的时候过滤@Component注解

这种方式下不区分Spring和SpringMVC的环境(这句话的意思是我们不需要显式地用@Component去定义SpringMVC和Spring的bean了(或者都扫同一个包?),也就是Spring和SpringMVC整合起来了,SpringMVC会用到Spring的bean)
ServletConfig
- public class ServletConfig extends AbstractDispatcherServletInitializer {
- @Override
- //加载SpringMVC的容器
- protected WebApplicationContext createServletApplicationContext() {
- AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();//初始化web容器
- context.register(SpringMVCConfig.class);
- return context;
- }
-
- @Override
- //设置哪些请求归属于SpringMVC处理
- protected String[] getServletMappings() {
- return new String[]{"/"};
- }
-
- @Override
- //加载Spring容器配置 这里加载Spring,不区分Spring和SpringMVC环境
- protected WebApplicationContext createRootApplicationContext() {
- AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();//初始化springIoC容器
- context.register(SpringConfig.class);
- return context;
- }
- }
ServletConfig优化(继承这个长长的东西)
代码量更少了
- public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
-
- @Override
- //加载Spring容器配置
- protected Class>[] getRootConfigClasses() {
- return new Class[]{SpringConfig.class};
- }
-
- @Override
- //加载SpringMVC的容器
- protected Class>[] getServletConfigClasses() {
- return new Class[]{SpringMVCConfig.class};
- }
-
- @Override
- //设置所有请求都归属于SpringMVC处理
- protected String[] getServletMappings() {
- return new String[]{"/"};
- }
- }