• UID80
  • 登录2017-03-01
  • 粉丝58
  • 关注21
  • 发帖1115
  • 主页
  • 金币6326枚
社区居民
忠实会员
原创写手
潇潇宇 发布于2015-12-09 22:29
0/1160

Servlet 3 + Spring MVC零配置:去除所有xml

楼层直达

在一些基于Spring/Spring MVC的Java Web项目中,总是会有一些xml配置文件,如web.xml、applicationContext.xml等,本文的目标即消灭这些xml配置文件,用代码和注解来代替。

由于本文是基于Servlet 3,所以首先需要准备支持Servlet 3的容器,例如Tomcat 7.0及以上版本、Jetty 8及以上版本。

1、去除web.xml

下面是一个典型的web.xml,包含Spring/Spring MVC的配置:


 
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	version="3.0">

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>
	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:dispatcher-servlet.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>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

</web-app>

 

Spring MVC提供了一个接口WebApplicationInitializer,用于替代web.xml配置文件。实现该接口的类会在Servlet容器启动时自动加载并运行。

将以上xml文件转换成Java代码:


 
public class MyWebAppInitializer implements WebApplicationInitializer {

	/**
	 * Servlet容器启动时会自动运行该方法
	 */
	@Override
	public void onStartup(ServletContext servletContext) throws ServletException {

		servletContext.setInitParameter("contextConfigLocation", "classpath:applicationContext.xml");

		ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcher", new DispatcherServlet());
		registration.setLoadOnStartup(1);
		registration.addMapping("/");
		registration.setInitParameter("contextConfigLocation", "classpath:dispatcher-servlet.xml");

		servletContext.addListener(new ContextLoaderListener());
	}
}

 

此时即可删除web.xml文件,程序同样可以运行。

2、去除Spring MVC配置文件dispatcher-servlet.xml

一个典型的Spring MVC配置文件如下:


 
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
 
    <mvc:annotation-driven />
     
    <context:component-scan base-package="com.xxg.controller" />
     
    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
     
</beans>

 

Spring提供了@Configuration注解用于替代xml配置文件,@Bean注解可以替代xml中的<bean>来创建bean。

将以上xml配置文件转换成Java代码:


 
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.xxg.controller")
public class WebConfig {
	
	@Bean
	public InternalResourceViewResolver internalResourceViewResolver() {
		InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
		viewResolver.setPrefix("/WEB-INF/jsp/");
		viewResolver.setSuffix(".jsp");
		return viewResolver;
	}
}

 

3、去除Spring配置文件applicationContext.xml

Spring的配置文件中内容可能会比较多,并且不同的项目会有不同的配置,以下提供了一个简单的配置:


 
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

	<context:component-scan base-package="com.xxg">
		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
	</context:component-scan>
	
	<context:property-placeholder location="classpath:config.properties"/>
	
	<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
	    <property name="driverClassName" value="${jdbc.driverClassName}"/>
	    <property name="url" value="${jdbc.url}"/>
	    <property name="username" value="${jdbc.username}"/>
	    <property name="password" value="${jdbc.password}"/>
	</bean>

</beans>

 

其中数据库的相关配置从config.properties配置文件读取:


 
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb
jdbc.username=root
jdbc.password=123456

 

将以上xml配置转换成Java代码:


 
@Configuration
@ComponentScan(basePackages = "com.xxg", excludeFilters = {@Filter(value = Controller.class)})
public class AppConfig {

	@Value("${jdbc.driverClassName}")
	private String driverClassName;

	@Value("${jdbc.url}")
	private String url;

	@Value("${jdbc.username}")
	private String username;
 
	@Value("${jdbc.password}")
	private String password;
 
	@Bean(destroyMethod = "close")
	public DataSource dataSource() {
		BasicDataSource dataSource = new BasicDataSource();
		dataSource.setDriverClassName(driverClassName);
		dataSource.setUrl(url);
		dataSource.setUsername(username);
		dataSource.setPassword(password);
		return dataSource;
	}

	/**
	 * 必须加上static
	 */
	@Bean
	public static PropertyPlaceholderConfigurer loadProperties() {
		PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();
		ClassPathResource resource = new ClassPathResource("config.properties");
		configurer.setLocations(resource);
		return configurer;
	}
}

 

除了上面的方法外,加载properties配置文件还可以使用@PropertySource注解:


 
@Configuration
@ComponentScan(basePackages = "com.xxg", excludeFilters = {@Filter(value = Controller.class)})
@PropertySource("classpath:config.properties")
public class AppConfig {

	@Value("${jdbc.driverClassName}")
	private String driverClassName;

	@Value("${jdbc.url}")
	private String url;

	@Value("${jdbc.username}")
	private String username;

	@Value("${jdbc.password}")
	private String password;

	@Bean(destroyMethod = "close")
	public DataSource dataSource() {
		BasicDataSource dataSource = new BasicDataSource();
		dataSource.setDriverClassName(driverClassName);
		dataSource.setUrl(url);
		dataSource.setUsername(username);
		dataSource.setPassword(password);
		return dataSource;
	}

	/**
	 * 必须加上static
	 */
	@Bean
	public static PropertySourcesPlaceholderConfigurer loadProperties() {
		PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
		return configurer;
	}
}

 

以上两种Java实现方式选择其中一种即可。

4、修改MyWebAppInitializer.java

完成以上步骤后,就可以去掉dispatcher-servlet.xml和applicationContext.xml等Spring配置文件,用Java代码替代了。

此时,第1步中的MyWebAppInitializer.java需要修改,不再读取xml配置文件,而是加载@Configuration注解的Java代码来配置Spring:


 
public class MyWebAppInitializer implements WebApplicationInitializer {

	/**
	 * Servlet容器启动时会自动运行该方法
	 */
	@Override
	public void onStartup(ServletContext servletContext) throws ServletException {

		AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
		rootContext.register(AppConfig.class);
		servletContext.addListener(new ContextLoaderListener(rootContext));

		AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();
		webContext.register(WebConfig.class);
		ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcher", new DispatcherServlet(webContext));
		registration.setLoadOnStartup(1);
		registration.addMapping("/");
	}
}

 

至此,便完成了Java程序替换xml配置文件所有工序。

 

原文来自:http://xxgblog.com/2015/07/09/spring-zero-xml/


0人打赏
您需要登录后才可以回帖
发表回复
极贡献
技术问答
专题荟萃
程序人生
视觉设计
Android开发
iOS开发
编程语言
前端开发
后端开发
服务器架构
软件测试
运维方案
创业路上



最热文章墙

  • 62705/348   【精品推荐】200多种Android动画效果的强悍框架,太全了,不看这个,再有动画的问题,不理你了^@^

  • 35025/189   情人节福利,程序员表白的正确姿势:改几行代码就变成自己的表白了

  • 32937/142   省时省力的Android组件群来了,非常棒的原型参考

  • 31056/236   【精品推荐】Android版产品级的音乐播放器源码,功能太强大了,最好的产品原型有木有?

  • 29067/0   Python爬虫:常用浏览器的useragent

  • 26769/2   超全!整理常用的iOS第三方资源

  • 25362/70   原创表白APP,以程序员的姿势备战新年后的7夕,持续完善中!

  • 23919/138   2016抢红包软件及源码

  • 20367/29   麻省理工的一帮疯子,真的实现了随意操控万物!(绝对黑科技)

  • 20217/25   Android工程师面试题大全

  • 19724/27   2016程序员跳槽全攻略

  • 19573/9   GitHub上排名前50的iOS项目:总有一款你用得着

  • 18901/20   码魂:程序员的牛B漫画

  • 17966/151   Android版类似UC浏览器:非常赞,产品级的源码

  • 17131/3   吐槽那些程序员的搞笑牛逼注释

  • 16614/10   2016年最全的Android面试考题+答案 精编版

  • 16045/1   iOS 动画总结

  • 15807/41   一个绚丽的loading动效分析与实现!

  • 15477/73   【持续更新中】Android福利贴(二):资料源码大放送

  • 15408/84   Android小而全的博客源码:非常适合全面掌握开发技巧

  • 15009/44   惊艳的App引导页:背景图片切换加各个页面动画效果

  • 14954/10   女程序员的梦,众网友的神回复

  • 14756/23   个人收集的Android 各类功能源代码

  • 14717/11   年会上现场review代码是怎么样的体验!

  • 14488/5   新一代Android渠道打包工具:1000个渠道包只需要5秒

  • 13845/23   珍藏多年的素材,灵感搜寻网站

  • 13733/53   基于瀑布流的美女图片浏览App,有注释的源代码

  • 13433/76   仿京东商城客户端Android最新版,不错的原型和学习资料

  • 13409/17   用JavaScript 来开发iOS和Android 原生应用:React Native开源框架中文版来啦

  • 13066/15   基于Android支付宝支付设计和开发方案

  • 12994/20   Android福利第三波【Android电子书】

  • 12985/94   Android带弹幕的视频播放器源码,来自大名鼎鼎的Bilibili弹幕网站

  • 12808/18   65条最常用正则表达式,你要的都在这里了

  • 12593/17   什么是真正的黑客:收获12200+Stars,人气远超微软开源VS

  • 12575/72   【精品推荐】类似360安全卫士安Android源码:非常赞的产品原型

  • 12335/0   iOS中文版资源库,非常全

  • 12050/7   用程序员的姿势抢过年的火车票

  • 12009/7   一张图搞定iOS学习路线,非常全面

  • 12001/11   有木有这样一张酷图帮你集齐所有git命令超实用

  • 11490/10   成为Java顶尖程序员 ,看这11本书就够了

  • 11242/18   一张图搞定Android学习路线,非常全面

  • 11183/10   微信支付终于成功了(安卓,iOS),在此分享

  • 11059/44   在线音乐播放器完整版(商用级的源码):非常赞,可听免费高品质专辑

  • 10924/3   基于Node.js的强大爬虫,能直接发布抓取的文章哦

  • 10807/0   GitHub iOS 库和框架Top100 

  • 10759/29   【持续更新中】Android福利贴(一):资料源码

  • 10258/4   46 个非常有用的 PHP 代码片段

  • 10202/61   【技巧一】搭配Android Studio,如何实现App远程真机debug?

  • 10033/3   即时通信第三方库

  • 9779/8   流媒体视频直播方案

  • 9740/9   烧了5亿美金,这家神秘的公司即将颠覆人类未来!

  • 9651/9   B站建开源工作组:APP想支持炫酷弹幕的看过来

  • 9525/18   八个最优秀的Android Studio插件

  • 9424/2   【精品推荐】高质量PHP代码的50个实用技巧:非常值得收藏

  • 9339/10   中国黑客的隐秘江湖:攻守对立,顶尖高手月入千万美元

  • 8890/6   开箱即用!Android四款系统架构工具

  • 8727/3   一张图看清Linux 内核运行原理

  • 8688/10   十大技巧快速提升Android应用开发性能

  • 8652/3   10款GitHub上最火爆的国产开源项目——可以媲美西半球

  • 8352/1   Android性能优化视频,文档以及工具

  • 返回顶部