@Beeder
2018-02-17T07:52:10.000000Z
字数 22183
阅读 675
javaWeb Spring
Spring是一个分层(分层架构)的JavaSE/EEfull-stack(一站式) 轻量级开源框架
Spring的核心是控制反转(IoC)和面向切面(AOP)
下载地址:http://repo.springsource.org/libs-release-local/org/springframework/spring
//IOC功能//日志相关的jar包//路径:spring-framework-3.0.2.RELEASE-dependencies/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1com.springsource.org.apache.commons.logging-1.1.1.jar//路径:pring-framework-3.0.2.RELEASE-dependencies\org.apache.log4j\com.springsource.org.apache.log4j\1.2.15com.springsource.org.apache.log4j-1.2.15.jar//spring相关核心jar包spring-beans-4.2.4.RELEASE.jarspring-context-4.2.4.RELEASE.jarspring-core-4.2.4.RELEASE.jarspring-expression-4.2.4.RELEASE.jar//AOP功能//spring的传统AOP的开发的包spring-aop-4.2.4.RELEASE.jarcom.springsource.org.aopalliance-1.0.0.jar//aspectJ的开发包com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jarspring-aspects-4.2.4.RELEASE.jar//整合web项目需要jar包//监听ServerletContext创建时加载applicationContext.xml(避免每次获取bean都进行加载)spring-web-4.2.4.RELEASE.jar//注解方式需要jar包spring-aop-4.2.4.RELEASE.jar//整合单元测试需要jar包spring-test-4.2.4.RELEASE.jar//Spring的JDBC//mysql驱动包mysql-connector-java-5.1.7-bin.jar//Spring框架JDBC相关包spring-jdbc-4.2.4.RELEASE.jarspring-tx-4.2.4.RELEASE.jar//整合dbcp连接池需要jar包com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jarcom.springsource.org.apache.commons.pool-1.5.3.jar//整合c3p0连接池需要jar包com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar
applicationContext.xml
命名可以改,默认为applicationContext.xml
路径:src目录下
| 属性 | 功能 | 特点 |
|---|---|---|
| id | 唯一ID约束 | 必须以字母开始,不可用特殊字符 |
| name | 可做id(无id情况) | 可出现特殊字符 |
| class | Bean对象的全路径 | |
| init-method | bean被载入到容器时调init-method指定方法 | |
| destroy-method | bean从容器中删除时调destroy-method指定方法 | 通常不会执行(执行前虚拟机就会关闭) |
//根目录:为src目录<import resource="applicationContext2.xml"/>
IoC -- Inverse of Control(控制反转)将对象的创建权反转给Spring
applicationContext.xml
命名可以改,默认为applicationContext.xml
路径:src目录下
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 使用bean标签 --><bean id="userService" class="com.itheima.demo2.UserServiceImpl"><property name="name" value="小凤"/></bean></bean>
java类
/*** 使用的是Spring框架的方式*/@Testpublic void run2(){// 创建工厂,加载核心配置文件//加载applicationContext.xml时,xml中的bean对象就会创建ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");// 从工厂中获取到对象UserServiceImpl usi = (UserServiceImpl) ac.getBean("userService");// 调用对象的方法执行usi.sayHello();}
Dependency Injection(依赖注入):在Spring框架创建Bean对象时,动态的将依赖对象注入到Bean组件中
applicationContext.xml
命名可以改,默认为applicationContext.xml
路径:src目录下
<bean id="us" class="com.itheima.demo1.UserServiceImpl"><!--property:通过UserServiceImpl提供的set方法将value赋值给属性(name值)--><property name="uname" value="小风"/></bean><!-- customerDao:需要引用的java对象 --><bean id="customerDao" class="com.itheima.demo3.CustomerDaoImpl"/><!--ref:引用bean对象,customerService中需要定义customerDao并提供set方法--><bean id="customerService" class="com.itheima.demo3.CustomerServiceImpl"><property name="customerDao" ref="customerDao"/></bean><!-- 构造方法的注入的方式 --><bean id="car1" class="com.itheima.demo4.Car1"><!--constructor-arg:将参数引入构造方法--><constructor-arg name="cname" value="奇瑞QQ"/><constructor-arg name="price" value="25000"/><!--根据构造方法参数下标位置引入值<constructor-arg index="0" value="囚车"/><constructor-arg index="1" value="545000"/>--></bean><!-- 注入集合:java类中都需要定义属性并提供set方法--><bean id="user" class="com.itheima.demo4.User"><!--注入数组--><property name="arrs"><list><value>哈哈</value><value>呵呵</value><value>嘿嘿</value></list></property><!--注入list集合--><property name="list"><list><value>美美</value><value>小凤</value></list></property><!--注入map集合--><property name="map"><map><entry key="aaa" value="小苍"/><entry key="bbb" value="小泽"/></map></property><!--注入Properties配置文件--><property name="pro"><props><prop key="username">root</prop><prop key="password">1234</prop></props></property></bean>
IOC的注解方式
@Component //作用在类上,相当于设置bean标签@PostConstruct //作用于init方法,相当于init-method属性@PreDestroy //作用于destroy方法,相当于destroy-method属性
IOC注解方式的依赖注入
@Value -- 用于注入普通类型
spring-aop-4.2.4.RELEASE.jar
applicationContext.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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here --><!--需要引入context约束--><!-- 开启注解的扫描 --><context:component-scan base-package="com.itheima"/></beans>
<bean id="userService" class="com.itheima.demo1.UserServiceImpl"> == @Component(value="userService")
bean类
/*** 组件注解,标记类* <bean id="userService" class="com.itheima.demo1.UserServiceImpl"> == @Component(value="userService")* @author Administrator*/@Component(value="userService")public class UserServiceImpl implements UserService {public void sayHell() {System.out.println("hello Spring!!");}//相当于init-method="init"@PostConstructpublic void init(){System.out.println("初始化...");}}
测试类
/*** 注解的方式*/@Testpublic void run2(){// 获取工厂,加载配置文件ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");// 获取对象UserService us = (UserService) ac.getBean("userService");us.sayHell();}
bean类
@Component(value="userService")public class UserServiceImpl implements UserService {// 给name属性注入“美美”的字符串,setName方法可以省略不写@Value(value="美美")private String name;/*public void setName(String name) {this.name = name;}*/// @Autowired //按类型自动装配// @Qualifier(value="userDao") // 按名称注入// 是Java的注解,Spring框架支持该注解@Resource(name="userDao")private UserDao userDao;public void sayHell() {System.out.println("hello Spring!!"+name);userDao.save();}}
避免每次调用都加载applicationContext.xml
引入jar包
//监听ServerletContext创建时加载applicationContext.xml(避免每次获取bean都进行加载)spring-web-4.2.4.RELEASE.jar
web.xml
<!-- 配置WEB整合的监听器 --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- 加载方式:默认只能加载WEB-INF目录下的配置文件,提供配置方式,加载src目录下 --><context-param><param-name>contextConfigLocation</param-name><!--根目录:src--><param-value>classpath:applicationContext.xml</param-value></context-param>
java类
/*(普通)使用工厂的方式ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");CustomerService cs = (CustomerService) ac.getBean("customerService");cs.save();*///避免每次调用都加载applicationContext.xmlServletContext servletContext = ServletActionContext.getServletContext();// 需要使用WEB的工厂的方式WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);CustomerService cs = (CustomerService) context.getBean("customerService");cs.save();
导入相关jar
//整合单元测试需要jar包spring-test-4.2.4.RELEASE.jar
java测试类
//运行SpringJUnit4ClassRunner.class@RunWith(SpringJUnit4ClassRunner.class)//加载applicationContext.xml@ContextConfiguration("classpath:applicationContext.xml")public class Demo2 {@Resource(name="userService")private UserService UserService;@Testpublic void run1(){// 原来:获取工厂,加载配置文件,getBean()UserService.sayHell();}}
学习原因:可以在不修改源代码的前提下,对程序进行增强
必须是面向接口的,只有实现了具体接口的类才能生成代理对象
对于没有实现了接口的类,也可以产生代理,产生这个类的子类的方式

//所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点1. Joinpoint(连接点)//所谓切入点是指我们要对哪些Joinpoint进行拦截的定义2. Pointcut(切入点)//所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)3. Advice(通知/增强)//引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field4. Introduction(引介)//代理的目标对象5. Target(目标对象)//是指把增强应用到目标对象来创建新的代理对象的过程6. Weaving(织入)//一个类被AOP织入增强后,就产生一个结果代理类7. Proxy(代理)// 是切入点和通知的结合,以后咱们自己来编写和配置的8. Aspect(切面)
引入相关jar包
//spring的传统AOP的开发的包spring-aop-4.2.4.RELEASE.jarcom.springsource.org.aopalliance-1.0.0.jar//aspectJ的开发包com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jarspring-aspects-4.2.4.RELEASE.jar
applicationContext.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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here --><!-- 配置客户的dao类 --><bean id="customerDao" class="com.itheima.demo3.CustomerDaoImpl"/><!-- 配置切面类:增强类,编写增强方法 --><bean id="myAspectXml" class="com.itheima.demo3.MyAspectXml"/><!-- 配置AOP --><aop:config><!-- 配置切面类:切入点 + 通知(类型) --><aop:aspect ref="myAspectXml"><!-- 配置的前置通知,save方法执行之前,增强的方法会执行 --><!-- 切入点的表达式:execution(public void com.itheima.demo3.CustomerDaoImpl.save()) --><!--method:(通知)增强方法pointcut:(切入点)需要增强的方法--><aop:before method="log" pointcut="execution(public void com.itheima.demo3.CustomerDaoImpl.save())"/></aop:aspect></aop:config></beans>
CustomerDaoImpl.java
//继承CustomerDao接口public class CustomerDaoImpl implements CustomerDao {public void save() {System.out.println("保存客户...");}public void update() {System.out.println("修改客户...");}}
测试类
/*** 测试AOP功能*/@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext3.xml")public class Demo3 {@Resource(name="customerDao")private CustomerDao customerDao;@Testpublic void run1(){customerDao.save();// customerDao.update();}}
/*环绕通知需手动执行目标对象的方法*//*** 环绕通知:方法执行之前和方法执行之后进行通知,默认的情况下,目标对象的方法不能执行的。需要手动让目标对象的方法执行*/public void around(ProceedingJoinPoint joinPoint){//目标对象的方法前执行System.out.println("环绕通知1...");try {// 手动让目标对象的方法去执行joinPoint.proceed();} catch (Throwable e) {e.printStackTrace();}//目标对象的方法后执行System.out.println("环绕通知2...");}
通知类型
配置通用的切入点
applicationContext.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:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 开启自动代理 --><aop:aspectj-autoproxy/><!-- 配置目标对象 --><bean id="customerDao" class="com.itheima.demo1.CustomerDaoImpl"/><!-- 配置切面类 --><bean id="myAspectAnno" class="com.itheima.demo1.MyAspectAnno"/></beans>
切面类
/*** 注解方式的切面类* 相当于配置 <aop:aspect ref="">标签*/@Aspectpublic class MyAspectAnno {/*** 通知类型:@Before前置通知(切入点的表达式)* 相当于配置<aop:before>标签*/@Before(value="MyAspectAnno.fn()")public void log(){System.out.println("记录日志...");}}/*** 自动定义切入点 @Pointcut*/@Pointcut(value="execution(public * com.itheima.demo1.CustomerDaoImpl.save())")public void fn(){}
//mysql驱动包mysql-connector-java-5.1.7-bin.jar//Spring框架JDBC相关包spring-jdbc-4.2.4.RELEASE.jarspring-tx-4.2.4.RELEASE.jar//整合dbcp连接池需要jar包com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jarcom.springsource.org.apache.commons.pool-1.5.3.jar//整合c3p0连接池需要jar包com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar
applicationContext.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:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 内置的连接池:先配置连接池(Spring自带模板类) --><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///spring_day03"/><property name="username" value="root"/><property name="password" value="root"/></bean><!--使用DBCP连接池:配置DBCP的连接池(只需引入jar和配置)<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///spring_day03"/><property name="username" value="root"/><property name="password" value="root"/></bean>--><!--使用C3P0连接池:配置DBCP的连接池 (只需引入jar和配置)<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///spring_day03"/><property name="username" value="root"/><property name="password" value="root"/></bean>--><!-- 配置JDBC的模板类 --><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"/></bean></beans>
/*** 测试JDBC的模板类,使用IOC的方式*/@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class Demo1_1 {@Resource(name="jdbcTemplate")private JdbcTemplate jdbcTemplate;@Testpublic void run1(){//操作数据库jdbcTemplate.update("insert into t_account values (null,?,?)", "小苍",10000);}/*** 测试查询:通过主键查询一条记录*/@Testpublic void run4(){Account ac = jdbcTemplate.queryForObject("select * from t_account where id = ?", new BeanMapper(), 1);System.out.println(ac);}/*** 自己手动的来封装数据(一行一行封装数据)* Account:JavaBean类,用于封装数据*/class BeanMapper implements RowMapper<Account>{public Account mapRow(ResultSet rs, int rowNum) throws SQLException {Account ac = new Account();ac.setId(rs.getInt("id"));ac.setName(rs.getString("name"));ac.setMoney(rs.getDouble("money"));return ac;}}}
JdbcDaoSupport类有定义jdbc模板类,且只需注入连接池对象便会创建模板类。可省略jdbc模板类

applicationContext.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:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 内置的连接池:先配置连接池(Spring自带模板类) --><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///spring_day03"/><property name="username" value="root"/><property name="password" value="root"/></bean><!-- 配置JDBC的模板类 --><!--<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"/></bean>--><bean id="accountDao" class="com.itheima.demo1.AccountDaoImpl"><!-- <property name="jdbcTemplate" ref="jdbcTemplate"/> --><property name="dataSource" ref="dataSource"/></bean></beans>
特性:原子性、一致性、隔离性、持久性
事务:指的是逻辑上一组操作,组成这个事务的各个执行单元,要么一起成功,要么一起失败!
TransactionStatus接口
事务的状态
总结:上述对象之间的关系:平台事务管理器真正管理事务对象.根据事务定义的信息TransactionDefinition 进行事务管理,在管理事务中产生一些状态.将状态记录到TransactionStatus中
事务隔离级别的常量
static int ISOLATION_DEFAULT //采用数据库的默认隔离级别static int ISOLATION_READ_UNCOMMITTEDstatic int ISOLATION_READ_COMMITTEDstatic int ISOLATION_REPEATABLE_READstatic int ISOLATION_SERIALIZABLE
事务的传播行为常量
先解释什么是事务的传播行为:解决的是业务层之间的方法调用!!
/*在同一个事务中*///A中有事务,使用A中的事务.如果没有,B就会开启一个新的事务,将A包含进来.(保证A,B在同一个事务中),默认值!!PROPAGATION_REQUIRED(默认值)//A中有事务,使用A中的事务.如果A中没有事务.那么B也不使用事务.PROPAGATION_SUPPORTS//A中有事务,使用A中的事务.如果A没有事务.抛出异常.PROPAGATION_MANDATORY/*不在同一个事务中*///A中有事务,将A中的事务挂起.B创建一个新的事务.(保证A,B没有在一个事务中)PROPAGATION_REQUIRES_NEW(记)//A中有事务,将A中的事务挂起.PROPAGATION_NOT_SUPPORTED//A中有事务,抛出异常.PROPAGATION_NEVER//嵌套事务.当A执行之后,就会在这个位置设置一个保存点.如果B没有问题.执行通过.如果B出现异常,运行客户根据需求回滚(选择回滚到保存点或者是最初始状态)PROPAGATION_NESTED(记)
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:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 配置C3P0的连接池 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="com.mysql.jdbc.Driver"/><property name="jdbcUrl" value="jdbc:mysql:///spring_day03"/><property name="user" value="root"/><property name="password" value="root"/></bean><!-- 配置平台事务管理器 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean><!-- 声明式事务(采用XML配置文件的方式) --><!-- 先配置通知 --><tx:advice id="myAdvice" transaction-manager="transactionManager"><tx:attributes><!-- 给方法设置数据库属性(隔离级别,传播行为) --><tx:method name="pay" propagation="REQUIRED"/></tx:attributes></tx:advice><!-- 配置AOP:如果是自己编写的AOP,使用aop:aspect配置,使用的是Spring框架提供的通知aop:advisor --><aop:config><!-- aop:advisor,是Spring框架提供的通知 --><aop:advisor advice-ref="myAdvice" pointcut="execution(public * com.itheima.demo2.AccountServiceImpl.pay(..))"/></aop:config><!-- 配置业务层和持久层 --><bean id="accountService" class="com.itheima.demo2.AccountServiceImpl"><property name="accountDao" ref="accountDao"/></bean><bean id="accountDao" class="com.itheima.demo2.AccountDaoImpl"><property name="dataSource" ref="dataSource"/></bean></beans>
业务层java类
public class AccountServiceImpl implements AccountService {private AccountDao accountDao;public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}/*** 转账的方法*/public void pay(final String out, final String in, final double money) {// 先扣钱accountDao.outMoney(out, money);// 加钱accountDao.inMoney(in, money);}}
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:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 配置C3P0的连接池 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="com.mysql.jdbc.Driver"/><property name="jdbcUrl" value="jdbc:mysql:///spring_day03"/><property name="user" value="root"/><property name="password" value="root"/></bean><!-- 配置平台事务管理器 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean><!-- 开启事务的注解 --><tx:annotation-driven transaction-manager="transactionManager"/><!-- 配置业务层和持久层 --><bean id="accountService" class="com.itheima.demo3.AccountServiceImpl"><property name="accountDao" ref="accountDao"/></bean><bean id="accountDao" class="com.itheima.demo3.AccountDaoImpl"><property name="dataSource" ref="dataSource"/></bean></beans>
业务层java类
/*** Transactional类上添加了注解,类中的所有的方法全部都有事务* @author Administrator*/@Transactionalpublic class AccountServiceImpl implements AccountService {private AccountDao accountDao;public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}/*** 转账的方法*/public void pay(final String out, final String in, final double money) {// 先扣钱accountDao.outMoney(out, money);// 模拟异常int a = 10/0;// 加钱accountDao.inMoney(in, money);}}