- 以前我们写的service,为图方便,就没有写IService接口,在使用时是自己new的,有两点需要指明:其一,如前面博文所说,最好写接口,并用反射的方式获取对象,这样换实现方式时,只用在配置文件中修改实现类名称,而无需改动源码;其二,之前我们并没有使用动态代理,所以要想引入事务,必须自己在业务层写commit,定义事务。
- Spring容器为我们提供了很好的解决方案。Spring的IoC/DI使得容器不但给我们反射所需的实例,还可以在配置文件中给实例注入属性,而且还提供了事务管理。要想容器给我们管理事务,service实例就交由容器动态代理。
- 面向切面,就是面向方法,在哪些方法里事务管理
- 如下的配置文件要谨记Beans3.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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
">
<!-- 配数据源BasicDataSource 要两个jar包,dbcp,pool-->
<!-- commons-dbcp-1.4.jar-->
<!-- commons-pool-1.6.jar-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="root1205"/>
<property name="defaultAutoCommit" value="true"/>
</bean>
<!-- 注入jdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 这里面要配数据源 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 将jdbcTemplate注入到PeopleService中 -->
<bean id="peopleService" class="com.service.PeopleService">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<!-- 配事务 需要spring里的aop,tx,[aspect]包还有另外的aopalliance.jar aspectjweaver.jar-->
<!-- 给数据源配事务管理,DataSourceTransactionManager-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 再使用tx标签,实现事务管理,这里tx标签不提示,要导入新的xsd -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.service.PeopleService.save(..))" id="txPointCut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
</beans>
- PeopleService.java
package com.service;
import org.springframework.jdbc.core.JdbcTemplate;
import com.entity.People;
public class PeopleService implements IPeopleService {
private JdbcTemplate jdbcTemplate;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public void save(People p) {
//通过在save方法里打断点的方式可以看到通过spring容器实现的动态代理,使得业务层的数据库操作具有了事务功能
//不用手动地每个方法里commit了
jdbcTemplate.execute("insert into person(id,name)values(5,'张卫健')");
jdbcTemplate.execute("insert into person(id,name)values(6,'张卫健2')");
}
}
- 测试类Demo2.java
package com.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import com.service.IPeopleService;
import com.service.PeopleService;
public class Demo2 {
/**
* @param args
*/
public static void main(String[] args) {
//使用jdbcTemplate操作数据库
//Ctrl+Shift+T可以查找某个类是否存在,找不到就是少包
//导入spring里的spring-jdbc-3.2.6.RELEASE.jar
// ApplicationContext app = new ClassPathXmlApplicationContext("Beans3.xml");
// JdbcTemplate jdbcTemplate = (JdbcTemplate) app.getBean("jdbcTemplate");
// System.out.println(jdbcTemplate);
// //要导入spring-tx-3.2.6.RELEASE.jar mysql-connector-java-5.1.7-bin.jar
// jdbcTemplate.execute("insert into person(id,name)values(5,'张卫健')");
// jdbcTemplate.execute("insert into person(id,name)values(6,'张卫健2')");
ApplicationContext app = new ClassPathXmlApplicationContext("Beans3.xml");
//spring中有两种代理方式,默认优先jdk代理,再cglib代理
//jdk代理必须使用接口,所以下面用的是接口,否则在代理时会报错
//cglib代理使用的是子类,可以不用接口,spring内置了cglib,否则要另外导入cglib包
//如下获得的peopleService是一个代理对象
IPeopleService peopleService = (IPeopleService) app.getBean("peopleService");
peopleService.save(null);
}
}
jar包图