使用全注解配置Spring MVC
Posted ykzhen2015
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用全注解配置Spring MVC相关的知识,希望对你有一定的参考价值。
在Spring 4中我们已经可以通过全配置来配置Spring MVC了。首先配置文件需要继承AbstractAnnotationConfigDispatcherServletInitializer,怎么样这个类的名字够长吧?
下面是博主的配置。
package com.ssm.chapter15.config;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class MyWebAppInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer
// Spring IoC容器配置
@Override
protected Class<?>[] getRootConfigClasses()
// 可以返回Spring的Java配置文件数组
return new Class<?>[] ;
// DispatcherServlet的URI映射关系配置
@Override
protected Class<?>[] getServletConfigClasses()
// 可以返回Spring的Java配置文件数组
return new Class<?>[] WebConfig.class ;
// DispatchServlet拦截请求匹配
@Override
protected String[] getServletMappings()
return new String[] "*.do" ;
这里有三个方法:
getRootConfigClasses:是一个可以配置Spring IoC容器的方法,你可以往它哪里加载Java配置类,这里可以配置数据库,Redis,MyBatis/Hibernate等信息。
getServletConfigClasses:是一个加载Spring MVC配置类的方法,你也可以加载Java配置类,主要配置关于Spring MVC的内容
getServletMappings:是一个配置DispactherServlet拦截的正则式,相当于我们Servlet的拦截配置。
注意,这个类不需要使用web.xml配置加载,它会由Spring MVC的机制加载,或许你会惊讶,它为什么会自动加载呢?那是因为在spring 3.1之后,它给了我们一个类,SpringServletContainerInitializer,那么这个类就继承了Servlet规范的ServletContainerInitializer,按照Servlet的规范,Java Web容器启动的时候,就会加载实现这个类的方法,于是在Java Web容器初始化的时候,这个类就会被我们加载进来了。那么让我们看看它的源码:
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
//WebApplicationInitializer的实现类列表
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...
//找到WebApplicationInitializer 的实现类,并创建它们的实例
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;
servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
AnnotationAwareOrderComparator.sort(initializers);
//调用onStartup方法
for (WebApplicationInitializer initializer : initializers)
initializer.onStartup(servletContext);
从源码中,可以看到它主要查找WebApplicationInitializer接口的类,进行创建,然后调用onStartup方法进行初始化。显然AbstractAnnotationConfigDispatcherServletInitializer和WebApplicationInitializer存在着必然的某种联系,它们的关系下图所示。
这样大家清楚了实际上AbstractAnnotationConfigDispatcherServletInitializer也是实现了WebApplicationInitializer,所以当我们继承它,那么久可以配置Spring MVC的两个上下文了。于是在没有任何配置的情况下Spring MVC就能自动的发现你继承了 AbstractAnnotationConfigDispatcherServletInitializer的配置类,把它加载进来。
从博主的配置中,大家可以看到加载了一个类——WebConfig,让我们看看它的庐山真面目:
package com.ssm.chapter15.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
//定义Spring MVC扫描的包
@ComponentScan("com.*")
//启动Spring MVC配置
@EnableWebMvc
public class WebConfig
/***
* 通过注解 @Bean 初始化视图解析器
* @return ViewResolver 视图解析器
*/
@Bean(name="internalResourceViewResolver")
public ViewResolver initViewResolver()
InternalResourceViewResolver viewResolver =new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
/**
* 初始化RequestMappingHandlerAdapter,并加载Http的Json转换器
* @return RequestMappingHandlerAdapter 对象
*/
@Bean(name="requestMappingHandlerAdapter")
public HandlerAdapter initRequestMappingHandlerAdapter()
//创建RequestMappingHandlerAdapter适配器
RequestMappingHandlerAdapter rmhd = new RequestMappingHandlerAdapter();
// HTTP JSON转换器
MappingJackson2HttpMessageConverter jsonConverter
= new MappingJackson2HttpMessageConverter();
//MappingJackson2HttpMessageConverter接收JSON类型消息的转换
MediaType mediaType = MediaType.APPLICATION_JSON_UTF8;
List<MediaType> mediaTypes = new ArrayList<MediaType>();
mediaTypes.add(mediaType);
//加入转换器的支持类型
jsonConverter.setSupportedMediaTypes(mediaTypes);
//往适配器加入json转换器
rmhd.getMessageConverters().add(jsonConverter);
return rmhd;
注意类上面的注解,博主也写了其内容,这里初始化了两个bean,一个视图解析器(ViewResolver),不知道啥的视图解析器的自己去打屁股,跟着还初始化了一个RequestMappingHandlerAdapter,这个是Spring 目前默认的HanlderAdapter,用来运行我们控制的东西,比较底层,改天在和大家谈谈。大家还可以看到博主还创建了一个MappingJackson2HttpMessageConverter,它是一个HttpMessageConverter接口的实现类,其中注册mediaType为JSON其意思就是,当我们的控制器的方法上注解了@ResponseBody的时候,Spring MVC就会把响应的消息类型转换为JSON,然后运行控制器,最后控制器返回的结果,通过mediaType的判断就能够找到MappingJackson2HttpMessageConverter,然后通过它就能够转换为JSON了(貌似这段文字没什么其他人讲过,是博主调试源码得来的,觉得赞的给我文章点个赞吧)。
跟着就可以测试了,让我们新建一个控制器。
package com.ssm.chapter15.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @author ykzhen2015
*/
@Controller
@RequestMapping("/test")
public class TestController
@RequestMapping("/printRole")
//处理器打印JSON数据
@ResponseBody
public Role printRole()
Role role = new Role();
role.setId(1L);
role.setRoleName("role_name_1");
role.setNote("note_1");
return role;
//内部类
class Role
Long id;
String roleName;
String note;
public Long getId()
return id;
public void setId(Long id)
this.id = id;
public String getRoleName()
return roleName;
public void setRoleName(String roleName)
this.roleName = roleName;
public String getNote()
return note;
public void setNote(String note)
this.note = note;
好了,这个就是控制器了,妥妥通过@ResponseBody将其响应类型变为了JSON,根据mediaType的匹配,等着返回后被MappingJackson2HttpMessageConverter转换为JSON。
我们对其进行测试,如下图:
怎么样还算简单吗?你学会了吗?学不会记得买笔者的新书《Java EE互联网轻量级框架整合开发——Spring + Spring MVC + MyBatis(SSM框架)和Redis实现》
预计8月份左右上市哦。
以上是关于使用全注解配置Spring MVC的主要内容,如果未能解决你的问题,请参考以下文章
Spring MVC学习—基于注解的Controller控制器的配置全解一万字
Spring MVC学习—Validation基于注解的声明式数据校验机制全解一万字
spring mvc 必须使用注解配置吗?可不可使用xml配置?求高手详解