使用spring集成其他技术,最基本的配置都是模板化的,比如配置视图模板引擎、数据库连接池、orm框架、缓存服务、邮件服务、rpc调用等,以spring的xml配置为例,我将这些配置过程整理出来,并不时更新,以备参考!
spring
在普通的java工程中引入spring,只需要配置以下依赖
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>3.2.17.RELEASE</version> </dependency>
实际开发中,如果你用了log4j等日志框架,最好排除掉spring对commons-logging的依赖,写demo就不用了
<exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions>
建一个spring-conf.xml,放在src/main/java目录(也就是所有包和类的根目录,即classpath),内容如下
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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"> <bean class="com.xmyself.Test" /> </beans>
建一个Test.java类,这个类就是spring-conf.xml文件中定义的那个bean
package com.xmyself; public class Test { public void test() { System.out.println("spring is running"); } }
写带有main方法的主类
package com.xmyself; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { @SuppressWarnings("resource") ApplicationContext context = new ClassPathXmlApplicationContext("spring-conf.xml"); Test test = context.getBean(Test.class); test.test(); } }
运行Main,就能看到“spring is running”输出
spring mvc
spring mvc是配置在web工程中的,使用spring mvc也只要配置一个依赖
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>3.2.17.RELEASE</version> </dependency>
整一个Test.java类,这是个controller
package com.xmyself.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class Test { @RequestMapping("/test") @ResponseBody public String test() { return "spring mvc is running"; } }
在src/main/resources目录下建一个spring目录,里面放一个mvc-init.xml,内容如下
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" 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.xmyself.controller" /> </beans>
这个配置文件扫描了Test.java,最后修改web.xml来加载这个配置文件
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>spring3mvc</display-name> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:/spring/mvc-init.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
初始化DispatcherServlet如果没有指定xml文件地址,spring默认去WEB-INF目录找[servlet-name]-servlet.xml,这里就是spring-servlet.xml
启动工程,浏览器访问 http:localhost:8080/springmvc/test 就能看到返回 test 值了
freemarker模板引擎
freemarker是一种严格遵循mvc模型的模板引擎,现在介绍它的spring mvc中的配置
配置依赖
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>3.2.17.RELEASE</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.23</version> </dependency>
为什么要依赖spring-context-support?因为freemarker使用的视图解析器是由spring提供的,这个解析器就在spring-context-support的jar中
在spring mvc的mvc-init.xml中配置freemarker
<!-- freemarker config --> <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <property name="templateLoaderPath" value="/WEB-INF/page/" /> </bean> <bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"> <property name="suffix" value=".ftl" /> <property name="contentType" value="text/html; charset=UTF-8" /> </bean>
配置freemarker的本质是初始化上面的两个bean,所以,你可以把这段配置写在任意的xml文件,只要spring mvc能加载就行
在WEB-INF目录建一个page目录,里面放一个freemarker.ftl文件,内容只有一句话“freemarker page 中文乱码测试”
最后,在控制器写一个方法
@RequestMapping("/freemarker") public String freemarker() { return "freemarker"; }
启动工程,访问 http://localhost:8080/springmvc/freemarker 就能看到“freemarker page 中文乱码测试”这句话了
thymeleaf模板引擎
thymeleaf也是一个mvc模型的模板引擎,它的后缀是.html,所以thymeleaf模板的好处是不用渲染就能看到内容,现在spring也是推荐用thymeleaf作为spring mvc的模板引擎
配置依赖
<dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring3</artifactId> <version>2.1.5.RELEASE</version> </dependency>
这是thymeleaf与spring连接用的jar,它依赖了thymeleaf的jar,对于spring3和spring4,thymeleaf的依赖是不同的,配置也稍有不同,这点要注意,下面就开始配置thymeleaf
<!-- thymeleaf config --> <bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver"> <property name="prefix" value="/WEB-INF/page/" /> <property name="suffix" value=".html" /> <property name="templateMode" value="HTML5" /> </bean> <bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine"> <property name="templateResolver" ref="templateResolver" /> </bean> <bean class="org.thymeleaf.spring3.view.ThymeleafViewResolver"> <property name="templateEngine" ref="templateEngine" /> <property name="characterEncoding" value="UTF-8" /> </bean>
这段配置放在spring mvc能读到的任意xml文件都可以
在WEB-INF目录建一个page目录,里面放一个thymeleaf.html,内容只有一行“thymeleaf page 中文乱码测试”
最后,在控制器写一个方法
@RequestMapping("/thymeleaf") public String thymeleaf() { return "thymeleaf"; }
启动工程,访问 http://localhost:8080/springmvc/thymeleaf就能看到“thymeleafpage 中文乱码测试”这句话了
tomcat pool数据库连接池
java的数据库连接池可能用dbcp、c3p0的人多一点,但这里介绍的是tomcat pool,而且是针对mysql数据库的配置过程
配置依赖
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.27</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jdbc</artifactId> <version>7.0.73</version> </dependency>
注意:tomcat-jdbc依赖了tomcat-juli
下面整一个Main.java来测试连接
package com.xmyself; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import org.apache.tomcat.jdbc.pool.DataSource; import org.apache.tomcat.jdbc.pool.PoolProperties; public class Main { public static void main(String[] args) throws Exception { PoolProperties p = new PoolProperties(); p.setUrl("jdbc:mysql://localhost:3306/mysql"); p.setDriverClassName("com.mysql.jdbc.Driver"); p.setUsername("root"); p.setPassword("root"); p.setJmxEnabled(true); p.setTestWhileIdle(false); p.setTestOnBorrow(true); p.setValidationQuery("SELECT 1"); p.setTestOnReturn(false); p.setValidationInterval(30000); p.setTimeBetweenEvictionRunsMillis(30000); p.setMaxActive(100); p.setInitialSize(10); p.setMaxWait(10000); p.setRemoveAbandonedTimeout(60); p.setMinEvictableIdleTimeMillis(30000); p.setMinIdle(10); p.setLogAbandoned(true); p.setRemoveAbandoned(true); p.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;" + "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"); DataSource datasource = new DataSource(); datasource.setPoolProperties(p); Connection con = null; try { con = datasource.getConnection(); Statement st = con.createStatement(); ResultSet rs = st.executeQuery("select * from user"); int cnt = 1; while (rs.next()) { System.out.println((cnt++) + ". Host:" + rs.getString("Host") + " User:" + rs.getString("User") + " Password:" + rs.getString("Password")); } rs.close(); st.close(); } finally { if (con != null) try { con.close(); } catch (Exception ignore) { } } } }
这个例子是tomcat官方文档给出的,运行结果如下
1. Host:localhost User:root Password:*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B 2. Host:127.0.0.1 User:root Password:*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B 3. Host:::1 User:root Password:*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B 4. Host:localhost User: Password: 5. Host:% User:root Password:*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B
那spring怎么集成tomcat pool呢?配置xml让spring加载就好了
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"> <property name="url" value="jdbc:mysql://localhost:3306/mysql" /> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="username" value="root" /> <property name="password" value="root" /> </bean>
这里配置的属性与官方例子set方法中的属性完全相同,其余的我就不配置了
然后写一个测试,这里以spring mvc为例,写一个controller,具体代码与上例相同
@Controller public class Test { @Autowired private DataSource dataSource; @RequestMapping("/test") @ResponseBody public String test() throws Exception { Connection con = dataSource.getConnection(); // 拿到con就可以操作了 return "spring mvc running"; } }
mybatis持久化框架
mybatis轻量级,配置简单,使用方便,我们在tomcat pool基础上来配置,当然,使用tomcat pool配置只是为了得到dataSource,如果你用dbcp、c3p0等连接池,只要修改下这个dataSource的配置就好,mybatis本身的配置不用修改
配置依赖
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.1</version> </dependency>
我们定义一个TestDao.java接口,这就是mybatis要实现的东西
package com.xmyself.dao; public interface TestDao { public String test(); }
在src/main/resources目录建一个mapper目录,里面放一个TestDao.xml,内容如下
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.xmyself.dao.TestDao"> <select id="test" resultType="java.lang.String"> select "test" </select> </mapper>
mybatis通过一个xml文件实现了TestDao.java接口,很显然,这个实现过程肯定要用到dataSource,接下来的配置就是将TestDao.java、TestDao.xml、dataSource三者关联起来,在spring的xml配置文件(哪个配置文件没关系,只要spring能加载)添加如下内容
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"> <property name="url" value="jdbc:mysql://localhost:3306/mysql" /> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="username" value="root" /> <property name="password" value="root" /> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath*:mapper/*.xml" /> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.xmyself.dao" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> </bean>
这个配置我其实有点疑惑,TestDao.xml中有对TestDao.java接口的声明,所以应该只需要将dataSource与TestDao.xml做关联就够了,但实际上我没有找到这种方式
这时候启动工程,spring加载过程会报错,其实我是故意的,^_^
Caused by: java.lang.ClassNotFoundException: org.mybatis.spring.SqlSessionFactoryBean
因为spring内部没有直接对mybatis的支持,所以需要依赖中间层jar包,另外,还需要spring-jdbc提供对dao的支持
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>3.2.17.RELEASE</version> </dependency>
我们整一个类来测试吧,还是以spring mvc为例,整一个controller
@Controller public class Test { @Autowired private TestDao testDao; @RequestMapping("/test") @ResponseBody public String test() throws Exception { System.out.println(testDao.test()); return "spring mvc is running"; } }
浏览器访问 http://localhost:8080/springmvc/test 就能看到后台输出“test”
redis缓存服务
redis是一种key-value非关系型数据库,特点是运行于内存中,速度快,作为缓存服务器非常不错,而java对redis数据库的访问是通过jedis完成的
配置依赖
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>
初始化jedis连接,假设redis服务器地址为:192.168.253.128,端口:6379
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxIdle" value="100" /> <property name="maxTotal" value="300" /> <property name="maxWaitMillis" value="1000" /> <property name="testOnBorrow" value="true" /> </bean> <bean id="jedisPool" class="redis.clients.jedis.JedisPool"> <constructor-arg index="0" ref="jedisPoolConfig" /> <constructor-arg index="1" value="192.168.253.128" type="java.lang.String" /> <constructor-arg index="2" value="6379" type="int" /> </bean>
这段代码放在哪没关系,只要spring能加载到,注意,构造器注入一定要指明type类型
然后我们整一个类来测试,以spring mvc为例,整一个controller
@Controller public class Test { @Autowired private JedisPool pool; @RequestMapping("/test") @ResponseBody public String test() { Jedis redis = pool.getResource(); redis.set("test", "test"); System.out.println(redis.get("test")); return "spring mvc is running"; } }
浏览器访问 http://localhost:8080/springmvc/test,就能看到后台输出“test”