一步一步地配置Spring

本文旨在从一个空工程一步一步地配置Spring,空工程见上一篇文章创建Maven父子工程

一、spring基本配置

1. 添加spring依赖

父工程pom.xml添加spring依赖

    <dependencyManagement>
        <dependencies>
            <!-- 使用spring的BOM管理依赖 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-framework-bom</artifactId>
                <version>4.2.6.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!-- spring配置开始 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- spring配置结束 -->
    </dependencies>

2. web.xml添加spring配置

修改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"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:META-INF/dispatcher.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></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>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>

3. 添加dispatcher.xml文件

在web工程的src/main/resources/META-INF目录下添加dispatcher.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"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
        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">

    <!-- 加入下面这两个配置才能支持注解功能 -->
    <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
    <bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

    <!-- 扫描包,如果用扫描则不用再写 <context:annotation-config /> -->
    <context:component-scan base-package="com.alan.controller" />
    <context:component-scan base-package="com.alan.service.impl" />
    <context:component-scan base-package="com.alan.dao.impl" />

</beans>

4. 添加controller/service/dao等类

下面直接贴出各实现类。

(1)TestDaoImpl.java

package com.alan.dao.impl;

import org.springframework.stereotype.Repository;

import com.alan.dao.TestDao;

@Repository("testDao")
public class TestDaoImpl implements TestDao {

    @Override
    public String test() {
        return "../index.html";
    }

}

(2)TestServiceImpl.java

package com.alan.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alan.dao.TestDao;
import com.alan.service.TestService;

@Service("testService")
public class TestServiceImpl implements TestService {

    @Autowired
    private TestDao testDao;

    @Override
    public String test() {
        return testDao.test();
    }

}

(3)TestController.java

package com.alan.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alan.service.TestService;

@RestController
@RequestMapping("/alan")
public class TestController {

    @Autowired
    private TestService testService;

    @RequestMapping("/test")
    public String test(){
        return testService.test();
    }

}

5. 访问

重新编译工程并启动tomcat,通过浏览器访问,如果出现以下内容则表示配置正确。

二、配置Json支持

6. 添加Json依赖

修改父工程的pom.xml,添加以下内容:

        <!-- json配置开始 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.4</version>
        </dependency>
        <!-- json配置结束 -->

7. 配置@ResponseBody返回Json

在web工程的dispatcher.xml文件中添加如下配置:

    <!-- 加入以下配置支持@ResponseBody返回Json格式 -->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean
                class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json;charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                        <value>text/plain;charset=UTF-8</value>
                    </list>
                </property>
                <!-- 为null字段时是否显示 -->
                <!-- <property name="features"> <list> <value>WriteMapNullValue</value>
                    <value>QuoteFieldNames</value> <value>WriteNullStringAsEmpty</value> </list>
                    </property> -->
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

8. 再次访问

重启tomcat,通过浏览器再次访问,如果返回以下内容表示配置@ResponseBody正确。

注:如果Controller类上注解为@RestController则相当于方法上注解了@ResponseBody。

9. 添加返回Model方法

新建Model,并添加对应的dao/service/controller方法返回此Model。

(1)TestModel.java

package com.alan.model;

public class TestModel {
    private Integer id;
    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

(2)TestDaoImpl.java

    @Override
    public TestModel testModel() {
        TestModel testModel = new TestModel();
        testModel.setId(1);
        testModel.setName("tt");
        return testModel;
    }

(3)TestServiceImpl.java

    @Override
    public TestModel testModel() {
        return testDao.testModel();
    }

(4)TestController.java

    @RequestMapping("/test-model")
    public TestModel testModel(){
        return testService.testModel();
    }

10. 访问

重启tomcat,通过浏览器访问,如果返回以下内容则表示json配置正确。

三、配置单元测试

11. 添加单元测试依赖

修改父工程pom.xml,添加单元测试依赖。

        <!-- 单元测试开始 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <!-- 单元测试结束 -->

12. 添加测试类

新建一个测试类。

package com.alan.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.alan.service.TestService;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath*:META-INF/dispatcher.xml")
public class UnitTest {
    @Autowired
    private TestService testService;

    @Test
    public void test(){
        String result = testService.test();
        System.out.println(result);
    }

}

13. 运行测试类

Run As –> JUnit Test,运行结果如下表示配置单元测试正确。

四、配置日志管理

此处介绍两种日志管理工具,一个是log4j,一个是logback。

(一)log4j

14. 添加log4j相关依赖

修改父工程的pom.xml,添加以下内容。

        <!-- 日志配置开始 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.5.8</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.5.8</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.5.8</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>
        <!-- 日志配置结束 -->

15. 添加log4j.properties

在web工程的src/main/resources目录下添加log4j.properties文件。

log4j.rootCategory=DEBUG, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n

log4j.category.org.springframework.beans.factory=DEBUG

修改log4j.rootCategory中的DEBUG为INFO/ERROR等即可输出相应级别的日志。

16. 测试log4j

修改单元测试类为如下。

package com.alan.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.alan.controller.TestController;
import com.alan.service.TestService;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath*:META-INF/dispatcher.xml")
public class UnitTest {

    private Logger logger = LoggerFactory.getLogger(UnitTest.class);

    @Autowired
    private TestService testService;

    @Test
    public void test(){
        logger.debug("---------------------测试开始----------------------------");
        String result = testService.test();
        System.out.println(result);
        logger.debug("---------------------测试结束----------------------------");
    }

}

运行测试类,如果输出结果为以下内容则表示log4j配置正确。

(一)logback

17. 添加logback依赖

修改父工程的pom.xml,删除之前log4j的依赖,添加logback相关的依赖。

        <!-- 日志配置开始 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.12</version>
        </dependency>
        <!-- logback配置开始 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.logback-extensions</groupId>
            <artifactId>logback-ext-spring</artifactId>
            <version>0.1.2</version>
        </dependency>
        <!-- logback配置结束 -->
        <!-- 日志配置结束 -->

18. 添加logback.xml文件

在web工程的src/main/resources目录下添加logback.xml文件,官网说会先检测classpath下的logback.groovy文件,如果没有再寻找logback-test.xml文件,最后才会找logback.xml文件,不过我们一般就直接使用logback.xml文件啦。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property name="log.base" value="E:/workspace/self/log/alan-springmvc" />
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}:%L -%msg%n</pattern>
        </encoder>
    </appender>
    <appender name="logfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <Encoding>UTF-8</Encoding>
        <File>${log.base}/alan-springmvc.log</File>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}:%L -%msg%n</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.base}/alan-springmvc-%d{yyyyMMdd}-%i.log</fileNamePattern>
            <MaxHistory>100</MaxHistory>
            <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <MaxFileSize>100MB</MaxFileSize>
            </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>
    <root level="debug">
        <appender-ref ref="stdout" />
        <appender-ref ref="logfile" />
    </root>
</configuration>

修改root元素的level属性为debug/info/error等即可输出相应级别的日志。

19. 添加logback监听

修改web工程的web.xml,添加以下内容。

    <!-- logback监听配置 -->
    <context-param>
        <param-name>logbackConfigLocation</param-name>
        <param-value>classpath:logback.xml</param-value>
    </context-param>
    <listener>
        <listener-class>ch.qos.logback.ext.spring.web.LogbackConfigListener</listener-class>
    </listener>

20. 测试logback

运行之前的单元测试类,如果输出以下内容则表示logback配置正确。

注:从log4j转到logback之前类中的写法完全不用改变,这是slf4j的威力。

打开日志文件(logback.xml中配置的第二个appender),如果看到以下内容表示logback配置正确。

注:../index.html这行是system.out.println输出的,所以不在日志文件中。

五、集成mybatis

本文采用bonecp管理数据库连接,数据库采用mysql。

21. 添加bonecp/mybatis/mysql/jdbc依赖

其中,mysql的依赖版本最好跟数据库保持一致,否则可能会出现连不上的情况。

        <!-- 连接池配置开始 -->
        <dependency>
            <groupId>com.jolbox</groupId>
            <artifactId>bonecp</artifactId>
            <version>0.8.0.RELEASE</version>
        </dependency>
        <!-- 连接池配置结束 -->
        <!-- mybatis配置开始 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.0</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-jdbc</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-test</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- mybatis配置结束 -->
        <!--mysql配置开始 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>
        <!--mysql配置结束 -->
        <!-- jdbc配置结束 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <!-- jdbc配置结束 -->

22. 添加spring-mybatis.xml

在web工程的src/main/resources/META-INF目录下增加配置文件spring-mybatis.xml。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    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-3.0.xsd
                        http://www.springframework.org/schema/aop
                        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                        http://www.springframework.org/schema/tx
                        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- 配置DataSource数据源 -->
    <bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource"
        destroy-method="close">
        <!-- 数据库驱动 -->
        <property name="driverClass" value="${jdbc_driverClassName}" />
        <!-- 相应驱动的jdbcUrl -->
        <property name="jdbcUrl" value="${jdbc_url}" />
        <!-- 数据库的用户名 -->
        <property name="username" value="${jdbc_username}" />
        <!-- 数据库的密码 -->
        <property name="password" value="${jdbc_password}" />

        <!-- /** Maximum age of an unused connection before it is closed off. */ -->
        <!-- 设置分区个数。这个参数默认为1,建议3-4(根据特定应用程序而定)。 为了减少锁竞争和改善性能,从当前线程分区(thread-affinity)中获取一个connection,
            也就是这个样子:partitions[Thread.currentThread().getId() % partitionCount]。 当拥有充足的短期(short-lived)的线程时候,这个参数设置越大,性能越好。
            当超过一定的阀值时,连接池的维护工作就可能对性能造成一定的负面影响(仅当分区上的connection使用耗尽时) -->
        <property name="partitionCount" value="${db.partitionCount}" />

        <!-- 设置每个分区含有connection最大个数。这个参数默认为2。如果小于2,BoneCP将设置为50。 比如:partitionCount设置为3,maxConnectionPerPartition设置为5,你就会拥有总共15个connection。
            注意:BoneCP不会将这些connection一起创建出来,而是说在需要更多connection的时候从minConnectionsPerPartition参数开始逐步地增长connection数量。 -->
        <property name="maxConnectionsPerPartition" value="${db.maxConnectionsPerPartition}" />

        <!-- 设置每个分区含有connection最大小个数。这个参数默认为0。 -->
        <property name="minConnectionsPerPartition" value="${db.minConnectionsPerPartition}" />

        <!-- 设置分区中的connection增长数量。这个参数默认为1。 当每个分区中的connection大约快用完时,BoneCP动态批量创建connection,
            这个属性控制一起创建多少个connection(不会大于maxConnectionsPerPartition)。 注意:这个配置属于每个分区的设置。 -->
        <property name="acquireIncrement" value="${db.acquireIncrement}" />

        <!-- 设置连接池阀值。这个参数默认为20。如果小于0或是大于100,BoneCP将设置为20。 连接池观察线程(PoolWatchThread)试图为每个分区维护一定数量的可用connection。
            这个数量趋于maxConnectionPerPartition和minConnectionPerPartition之间。这个参数是以百分比的形式来计算的。
            例如:设置为20,下面的条件如果成立:Free Connections / MaxConnections < poolAvailabilityThreshold;就会创建出新的connection。
            换句话来说连接池为每个分区至少维持20%数量的可用connection。 设置为0时,每当需要connection的时候,连接池就要重新创建新connection,这个时候可能导致应用程序可能会为了获得新connection而小等一会。 -->
        <property name="poolAvailabilityThreshold" value="${db.poolAvailabilityThreshold}" />

        <!-- 设置获取connection超时的时间。这个参数默认为Long.MAX_VALUE;单位:毫秒。 在调用getConnection获取connection时,获取时间超过了这个参数,就视为超时并报异常。 -->
        <property name="connectionTimeoutInMs" value="${db.connectionTimeoutInMs}" />

        <!-- /** A connection older than maxConnectionAge will be destroyed and
            purged from the pool. */ -->
        <!-- 设置connection的存活时间。这个参数默认为0,单位:毫秒。设置为0该功能失效。 通过ConnectionMaxAgeThread观察每个分区中的connection,不管connection是否空闲,
            如果这个connection距离创建的时间大于这个参数就会被清除。当前正在使用的connection不受影响,直到返回到连接池再做处理。 -->
        <!-- 48小时关闭一个链接 -->
        <property name="maxConnectionAgeInSeconds" value="${db.maxConnectionAgeInSeconds}" />

        <!-- /** SQL statement to use for keep-alive/test of connection. */ -->
        <property name="connectionTestStatement" value="${db.connectionTestStatement}" />

        <!-- 设置connection的空闲存活时间。这个参数默认为60,单位:分钟。设置为0该功能失效。 通过ConnectionTesterThread观察每个分区中的connection,如果这个connection距离最后使用的时间大于这个参数就会被清除。
            注意:这个参数仅和idleConnectionTestPeriodInSeconds搭配使用,而且不要在这里设置任何挑衅的参数! -->
        <!-- 1小时回收空闲链接 -->
        <property name="idleMaxAgeInMinutes" value="${db.idleMaxAgeInMinutes}" />

        <!-- /** Connections older than this are sent a keep-alive statement. */ -->
        <!-- 设置测试connection的间隔时间。这个参数默认为240*60,单位:分钟。设置为0该功能失效。 通过ConnectionTesterThread观察每个分区中的connection,
            如果这个connection距离最后使用的时间大于这个参数并且距离上一次测试的时间大于这个参数就会向数据库发送一条测试语句,如果执行失败则将这个connection清除。
            注意:这个值仅和idleMaxAge搭配使用,而且不要在这里设置任何挑衅的参数! -->
        <!-- 4小时检测一次空闲链接 -->
        <property name="idleConnectionTestPeriodInMinutes" value="${db.idleConnectionTestPeriodInMinutes}" />

        <!-- /** After attempting to acquire a connection and failing, try to connect
            these many times before giving up. */ -->
        <!-- 设置重新获取连接的次数。这个参数默认为5。 获取某个connection失败之后会多次尝试重新连接,如果在这几次还是失败则放弃。 -->
        <property name="acquireRetryAttempts" value="${db.acquireRetryAttempts}" />

        <!-- 设置重新获取连接的次数间隔时间。这个参数默认为7000,单位:毫秒。如果小于等于0,BoneCP将设置为1000。 获取connection失败之后再次尝试获取connection的间隔时间。 -->
        <property name="acquireRetryDelayInMs" value="${db.acquireRetryDelayInMs}" />

        <!-- 设置连接池初始化功能。这个参数默认为false。 设置为true,连接池将会初始化为空,直到获取第一个connection。 -->
        <property name="lazyInit" value="${db.lazyInit}" />

        <!-- 设置是否关闭JMX功能。这个参数默认为false。 -->
        <property name="disableJMX" value="${db.disableJMX}" />

        <!-- 设置连接池名字。用于当作JMX和助手线程名字的后缀。 -->
        <property name="poolName" value="${db.poolName}" />

        <!-- /** Min no of prepared statements to cache. */ -->
        <!-- 设置statement缓存个数。这个参数默认为0。 -->
        <property name="statementsCacheSize" value="${db.statementsCacheSize}" />

        <!-- 设置是否开启记录SQL语句功能。这个参数默认是false。 将执行的SQL记录到日志里面(包括参数值)。 -->
        <property name="logStatementsEnabled" value="${db.logStatementsEnabled}" />

        <!-- 设置执行SQL的超时时间。这个参数默认为0;单位:毫秒。 当查询语句执行的时间超过这个参数,执行的情况就会被记录到日志中。 设置为0时,该功能失效。 -->
        <property name="queryExecuteTimeLimitInMs" value="${db.queryExecuteTimeLimit}" />
    </bean>

    <!-- 对数据源进行事务管理 -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager" />

    <!-- 配置SqlSessionFactoryBean -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- mapper和resultmap配置路径 -->
        <property name="mapperLocations">
            <list>
                <value>classpath:mapper/*Mapper.xml</value>
            </list>
        </property>
    </bean>

    <!-- 通过扫描的模式 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.alan.mapper" />
    </bean>

</beans>

23. 修改dispatcher.xml

(1)增加对属性文件读取的支持;

    <!-- 本工程属性配置文件 -->
    <bean id="configProperties"
        class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="locations">
            <list>
                <value>file:/etc/*.properties</value>
                <value>file:/E:/workspace/self/etc/*.properties</value>
            </list>
        </property>
        <property name="fileEncoding" value="utf-8" />
    </bean>
    <bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
        <property name="properties" ref="configProperties" />
    </bean>

(2)引入spring-mybatis.xml文件

    <import resource="classpath:META-INF/spring-mybatis.xml" />

24. 添加jdbc.properties

在E:/workspace/self/etc目录下增加数据库连接配置文件jdbc.properties。

jdbc_driverClassName=com.mysql.jdbc.Driver
jdbc_url=jdbc:mysql://127.0.0.1:3306/fcuh_user?useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&useOldAliasMetadataBehavior=true&noAccessToProcedureBodies=true
jdbc_username=admin
jdbc_password=1234

#Number of partitions.
db.partitionCount=3
#Min number of connections per partition.
db.minConnectionsPerPartition=2
#Max number of connections per partition.
db.maxConnectionsPerPartition=10
#Number of new connections to create in 1 batch.
db.acquireIncrement=2
#Time to wait before a call to getConnection() times out and returns an error.
db.connectionTimeoutInMs=30000
#Number of release-connection helper threads to create per partition.
#A connection older than maxConnectionAge will be destroyed and purged from the pool.
db.maxConnectionAgeInSeconds=172800
#SQL statement to use for keep-alive/test of connection.
db.connectionTestStatement=select 1 from dual
#Maximum age of an unused connection before it is closed off.
db.idleMaxAgeInMinutes=60
#Connections older than this are sent a keep-alive statement.
db.idleConnectionTestPeriodInMinutes=60
#After attempting to acquire a connection and failing, try to connect these many times before giving up.
db.acquireRetryAttempts=5
#After attempting to acquire a connection and failing, wait for this value before attempting to acquire a new connection again.
db.acquireRetryDelayInMs=5000
#If set to true, the connection pool will remain empty until the first connection is obtained.
db.lazyInit=false
#Set to true to disable JMX.
db.disableJMX=false
#Name of the pool for JMX and thread names.
db.poolName=logistics
#Min no of prepared statements to cache.
db.statementsCacheSize=50
#If set to true, log SQL statements being executed.
db.logStatementsEnabled=false
#Queries taking longer than this limit to execute are logged.
db.queryExecuteTimeLimit=0
#Create more connections when we hit x% of our possible number of connections.
db.poolAvailabilityThreshold=60

25. 修改dao/service/controller/mapper类

修改dao/service/controller类,在dao工程添加新的包com.alan.mapper,并添加新类TestMapper.java。

注:主要测试select/update/事务操作。

(1)TestMapper.java

package com.alan.mapper;

import java.util.List;

public interface TestMapper {
    List<Object> testDB();

    int testUpdate();

    int testInsert();
}

(2)TestDaoImpl.java

package com.alan.dao.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.alan.dao.TestDao;
import com.alan.mapper.TestMapper;
import com.alan.model.TestModel;

@Repository("testDao")
public class TestDaoImpl implements TestDao {
    @Autowired
    private TestMapper testMapper;

    @Override
    public String test() {
        return "../index.html";
    }

    @Override
    public TestModel testModel() {
        TestModel testModel = new TestModel();
        testModel.setId(1);
        testModel.setName("tt");
        return testModel;
    }

    @Override
    public List<Object> testDB() {
        return testMapper.testDB();
    }

    @Override
    public int testUpdate(){
        return testMapper.testUpdate();
    }

    @Override
    public int testInsert(){
        return testMapper.testInsert();
    }
}

(3)TestServiceImpl.java

注:testTx()方法会抛出异常以便测试事务。

package com.alan.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alan.dao.TestDao;
import com.alan.model.TestModel;
import com.alan.service.TestService;

@Service("testService")
public class TestServiceImpl implements TestService {

    @Autowired
    private TestDao testDao;

    @Override
    public String test() {
        return testDao.test();
    }

    @Override
    public TestModel testModel() {
        return testDao.testModel();
    }

    @Override
    public List<Object> testDB() {
        return testDao.testDB();
    }

    @Override
    public int testUpdate(){
        return testDao.testUpdate();
    }

    @Override
    public int testInsert(){
        return testDao.testInsert();
    }

    @Override
    @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class)
    public void testTx(Integer nullInt){
        testUpdate();
        nullInt.intValue();
        testInsert();
    }

}

(4)testController.java

package com.alan.controller;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alan.model.TestModel;
import com.alan.service.TestService;

@RestController
@RequestMapping("/alan")
public class TestController {
    private Logger logger = LoggerFactory.getLogger(TestController.class);

    @Autowired
    private TestService testService;

    @RequestMapping("/test")
    public String test(){
        logger.debug("enter into test");
        return testService.test();
    }

    @RequestMapping("/test-model")
    public TestModel testModel(){
        return testService.testModel();
    }

    @RequestMapping("/test-db")
    public List<Object> testDB(){
        return testService.testDB();
    }

    @RequestMapping("/test-update")
    public int testUpdate(){
        return testService.testUpdate();
    }

    @RequestMapping("/test-tx")
    public String testTx(){
        testService.testTx(null);
        return "success";
    }
}

26. 添加TestMapper.xml

在dao工程的src/main/resources/mapper目录下,添加TestMapper.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.alan.mapper.TestMapper" >
  <select id="testDB" resultType="map">
    select user_id, mobile from basic_user_info limit 10
  </select>

  <update id="testUpdate">
    update basic_user_info
    set mobile = ‘12345678911‘
    where user_id = 1
  </update>

  <insert id="testInsert">
    insert into basic_user_info(user_id,mobile,status)
    values(3,‘123x456x789‘,1)
  </insert>
</mapper>

27. 测试

前提:数据库建好了表,并插入了相关数据,至少包含3列:user_id,mobile,status。

(1)测试select

(2)测试update

(3)测试事务

浏览器报错,后台日志回滚,数据库未插入id为3的数据,说明事务测试成功。

至此,表示mybatis配置正确,并支持事务。

六、配置通用dao/service

~~~~~~~~~~~未完待续~~~~~~~~~~~~~~~~~~~~~~~

时间: 2024-10-12 20:16:21

一步一步地配置Spring的相关文章

【一步一步入门Spring+Maven+MongoDB】一:环境配置

[一步一步入门Spring+Maven+MongoDB]一:环境配置 一.开发环境 Eclipse(Java EE 版) 二.环境配置 1.jdk配置 1.1.1下载JDK 下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html,找到对应版本,下载安装. 1.1.2 配置环境变量 打开环境变量,系统变量,新建,变量名JAVA_HOME,变量值:上述安装路径(到bin父目录为止). 找到P

Spring Boot入门,一步一步简化,实现Spring Web项目开发

一. Spring Boot介绍 Spring Boot诞生的目的就是用来简化Spring应用开发过程.该框架使用了特定的方式来进行配置,从而使得开发人员不在需要定义一系列样板化的配置文件,而专注于核心业务开发.帮助开发人员快速的构建出基于Spring的应用.它会在后台整合项目所需的第三方依赖类库或框架,不再需要编写复杂的XML配置文件,仅通过几行代码就能实现一个可运行的Web应用. 直接嵌入 Tomcat 或 Jetty 服务器,不需要部署 WAR 文件. 提供许多基于Maven的 POM配置

一步一步学习Swift之(一):关于swift与开发环境配置

一.什么是Swift? 1.Swift 是一种新的编程语言,用于编写 iOS 和 OS X 应用. 2.Swift 结合了 C 和 Objective-C 的优点并且不受 C 兼容性的限制. 3.Swift 采用安全的编程模式并添加了很多新特性,这将使编程更简单,更灵活,也更有趣. 4.Swift 是基于成熟而且倍受喜爱的 Cocoa 和 Cocoa Touch 框架,它的降临将重新定义软件开发. 5.Swift 是编写 iOS 和 OS X 应用的极佳手段,并将伴随着新的特性和功能持续演进.

【一步一步走(1)】远程桌面软件VNC的安装与配置

最近在VPS上搭建Python Web环境,走了很多弯路,借此记下. 先说说购买的VPS(PhotonVPS),我可不是打广告,只是感觉这个VPS服务提供商还不错推荐给你大家,我之前也是体验过阿里云的,体验结果就不说了,反正不适合我. 使用系统是CentOS 64位,版本是 6.5,至于VNC的介绍,大家可以移步官网查看,下面就开始VNC的下载与配置了. 1. 通过SSH远程连接VPS主机,Windows的小伙伴们可以下载SSH客户端进行连接. ssh [用户名]@[IP地址] 2. 通过yum

学习Java的第一步 JDK 环境变量配置

JDK 环境变量配置 1.安装完JDK后配置环境变量  计算机→属性→高级系统设置→高级→环境变量 2.系统变量→新建 JAVA_HOME 变量 .变量值填写jdk的安装目录(我的安装目录是C:\Program Files\Java\jdk1.7.0_71 3.系统变量→寻找 Path 变量→编辑 在变量值最后输入 %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin; (注意原来Path的变量值末尾有没有;号,如果没有,先输入:号再输入上面的代码) 4.系统变量→新建 CLA

一步一步配置source insight

自从老大让用source insight以来,慢慢的喜欢上了这个功能强大的代码编辑器.下面是我一步一步配置source insight的过程,给后来人分享一下: 一.让source insight 默认编码格式为uft-8: 参考:[http://blog.csdn.net/nyist327/article/details/39935379] 二.解决每次只删除半个汉字的问题: 参考:[http://blog.csdn.net/nyist327/article/details/42419569]

一步一步学Spring.NET——Spring.NET环境准备

Spring.NET 1.3.2下载地址:http://down.51cto.com/data/861700 下载后解压 Spring.NET-1.3.2.7z:这个里面有我们需要用到的所有东西. Spring.NET-1.3.2.exe:安装文件 Spring.NET-1.3.2-API.chm:帮助文档 NHibernate 3.2 的下载地址: http://sourceforge.net/projects/nhibernate/files/NHibernate/3.2.0GA/ 点击上面

用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建三:配置spring并测试

这一部分的主要目的是 配置spring-service.xml  也就是配置spring  并测试service层 是否配置成功 用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建二:配置MyBatis 并测试(2 配置spring-dao和测试)在这个基础上面 继续进行spring的配置. 回顾上面  我们已经成功测试通过了Mybatis的配置. 这时候的目录结构是: 一:下面我们继续补充目录结构,在com.peakfortake的文件目录项目 

JAVAEE——spring02:使用注解配置spring、sts插件、junit整合测试和aop演示

一.使用注解配置spring 1.步骤 1.1 导包4+2+spring-aop 1.2 为主配置文件引入新的命名空间(约束) 1.3 开启使用注解代替配置文件 1.4 在类中使用注解完成配置 2.将对象注册到容器 //<bean name="user" class="cn.itcast.bean.User" /> //@Component("user") // @Service("user") // servic