Spring MVC全注解配置 - 无web.xml

Serlvet 3以后,我们可以使用注解来配置Servlet,对于像Spring这类的框架来说是一个很好的适应。Spring也对此特性加入了很多的新功能。本文就将简单的对之前的xml配置转换为java代码的配置。代码配置让程序员们觉得更加具有流程化,不像配置很多代码程序员们都不愿意look into。


接下来,进行替换我们之前的web.xmlspring-mvc.xml的配置。也就是在你的web工程里面看不到这两个配置文件了。(可能有的童鞋会说,这样配置可能对以后的修改不方便,无法达到只修改配置文件就切换某些环境。其实不是,零配置文件只是修改了类定义的配置,并没有修改之前配置文件的灵活性。我想无论谁也不会在之前的web.xml中去修改某个servlet的配置吧。况且这些所谓的配置文件灵活性,只是针对某个值,我们可以写在我们的properties文件里面,而且Spring对这类配置文件有很好的支持,而且使用很方便,有兴趣的童鞋可以去search一下。所以请打消这个配置不灵活的念头)。


切入正题,首先我们要替换web.xml。在Spring MVC中配置DispatchServlet,该类是 Spring MVC的核心类(该类具体作用请参考Spring MVC相关文档)。也就是在容器启动的时候就要初始化该类,并且配置相应的参数。

之前我们的web.xml中对DispatchServlet的配置如下:

<servlet>
   <servlet-name>dispatcher</servlet-name>
   <servlet-class>
     org.springframework.web.servlet.DispatcherServlet
   </servlet-class>
   <init-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
   </init-param>
   <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>dispatcher</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>


Servlet3 以后,支持动态的添加Servlet配置,请参考ServletContext.addServlet方法。因此我们可以使用Spring MVC提供的AbstractDispatcherServletInitializer类。该类是的类关系是AbstractDispatcherServletInitializer -> WebApplicationInitializer,(点击查看WebApplicationInitializer详解)AbstractDispatcherServletInitializer中重写onStartup方法,调用ServletContext.addServlet来实现注册该servlet。通过查看AbstractDispatcherServletInitializer源码,发现只需用重写他的三个方法既可以完成对DispatchServlet的注册。详细请看示例代码:

public class WebInitialConfiguration extends
		AbstractDispatcherServletInitializer {

	@Override
	protected WebApplicationContext createServletApplicationContext() {
		AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
		// scan the class under the demo.config package with @Configuration annotation 
		// You can add it by manually such as:
		// context.register(Class<?>... annotatedClasses) -> context.register(WebMVCConfiguration.class, AppConfig.class, ....)
		// This configuration like:
		// <init-param>
	    // 		<param-name>contextConfigLocation</param-name>
	    // 		<param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
	    // </init-param>
	    // all the configuration classes are in the same package, so use the getClass() method to get the package. Here the package name is com.sample.config
		context.scan(ClassUtils.getPackageName(getClass()));
		return context;
	}

	@Override
	protected String[] getServletMappings() {
		// Set the URL mapping
		return new String[] { "/" };
	}

	@Override
	protected WebApplicationContext createRootApplicationContext() {
		return null;
	}
}


细心的童鞋可以查看一下AbstractDispatcherServletInitializer的源码,会发现在代码中调用了ContextServlet.addServlet方法的:

DispatcherServlet dispatcherServlet = new DispatcherServlet(servletAppContext);
		ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, dispatcherServlet);


这时我们启动servlet3容器(本文使用tomcat7), 你会看到如下启动信息:

INFO: Initializing Spring FrameworkServlet 'dispatcher'
INFO: FrameworkServlet 'dispatcher': initialization started
Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler]
INFO: FrameworkServlet 'dispatcher': initialization completed in 843 ms



接下,替换spring-mvc.xml,在该配置中,我们只需用去配置很少几部分就可以借助Spring提供的接口完成对所有controller的注册和对视图解析的配置。

xml配置如下:

<context:component-scan base-package="com.sample.controller"/>
<context:annotation-config/>
<!-- This tag registers the DefaultAnnotationHandlerMapping and
         AnnotationMethodHandlerAdapter beans that are required for Spring MVC  -->
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
     <propertyname="prefix"value="/WEB-INF/pages/"/>
     <propertyname="suffix"value=".jsp"/>
</bean>
 
<!-- This tag allows for mapping the DispatcherServlet to "/" -->
<mvc:default-servlet-handler/>


首先,在Spring MVC中,我们可以使用@Configuration来进行Spring的配置,我们刚才也有需要去扫描这一类的配置类。接下来就是需要开启Spring MVC的具体配置。使用@EnableWebMvc,该注解等同于<mvc:annotation-driven/>,该标签具体的意思请看xml配置中对该标签的解释。


接下来我们要去扫描我们的controller,即有@Controller的类。因此我们使用@ComponentScan进行扫描,该注解等同于<context:componet-scan>。


Spring MVC需要对视图的解析进行一次定义,因此我们需要在该类中实例化一个ResourceViewResolver,该类的定义视具体需要而定。


具体的代码如下:


@Configuration
// <mvc:annotation-driven/>
@EnableWebMvc
@ComponentScan(basePackages={"com.sample.controller"})
public class WebMVCConfiguration extends WebMvcConfigurerAdapter {

	// equals: <mvc:default-servlet-handler/>
	@Override
	public void configureDefaultServletHandling(
			DefaultServletHandlerConfigurer configurer) {
		configurer.enable();
	}

	// add the resolver
	@Bean
	public InternalResourceViewResolver internalResourceViewResolver() {
		InternalResourceViewResolver resolver = new InternalResourceViewResolver();
		resolver.setPrefix("/WEB-INF/pages/");
		resolver.setSuffix(".jsp");
		return resolver;
	}
}


此时我们添加我们的controller到com.sample.controller包下,然后定义我们的requestmapping,再次启动server,你会看到会增加之前检测到的controller的信息。

INFO: Mapped "{[/test],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.sample.controller.TestController.test()


至此,简单的替换已经完成,更多的功能会在后续的文章中继续加入,如:spring-security, thymeleaf(一个很不错的视图框架)。

你可能感兴趣的:(spring,mvc,零配置)