Java - 框架之 Spring
一. IOC 和 DI
IOC : 控制反转,将对象的创建权反转给了 Spring。
DI : 依赖注入,前提是必须要有 IOC 的环境,Spring 管理这个类的时候将类的依赖的属性注入(设置)进来。
二. 工厂类
// 1. 加载类路径
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.save(); // 2. 加载磁盘中的 文件路径
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("C:/Users/Administrator/Desktop/applicationContext.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.save();
三. Bean 的作用范围配置 (xml 文件中)
1. scope : Bean 的作用范围。
! - singleton : 默认,Spring 会采用单例模式创建这个对象。
! - prototype : 多例模式。(Struts2 和 Spring 整合时会用到)
- request : 应用在 Web 项目中,Spring 创建这个类以后,将这个类存入到 request 范围中。
- session : 应用在 Web 项目中,Spring 创建这个类以后,将这个类存入到 session 范围中。
- globalsession : 应用在 Web 项目中,必须在 porlet 环境下使用,如果没有这个环境,相对于 session。
四. Spring 的属性注入方式(xml)
1. 构造方法
// 构造方法 (需要提供构造器)
<!-- 1. 构造方法 -->
<bean id="shop" class="com.q.spring.demo2.ShopDao">
<constructor-arg name="name" value="apple" />
<constructor-arg name="price" value="100" />
</bean>
@Test
public void demo1(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
ShopDao shopDao = (ShopDao) applicationContext.getBean("shop");
System.out.println(shopDao); }
2. set 方式的属性注入
<!-- 2. set 方法 -->
<bean id="shop2" class="com.q.spring.demo2.ShopDao2">
<property name="name" value="pear" />
<property name="price" value="22" />
</bean> <!-- 2. set 方法 (p名称空间属性注入) -->
<bean id="shop2" class="com.q.spring.demo2.ShopDao2" p:name="q" p:price="2222"></bean> <!-- 2. set 方法 (SpEL 属性注入) -->
<bean id="shop2" class="com.q.spring.demo2.ShopDao2">
<property name="name" value="#{'q1'}"></property>
<property name="price" value="#{111}"></property>
</bean>
// set 方式的属性注入(需要提供 set 方法)
@Test
public void demo2(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
ShopDao2 shopDao = (ShopDao2) applicationContext.getBean("shop2");
System.out.println(shopDao); }
3. set 方法注入对象类型 (属性中依赖类)
<!-- 3. set 方法注入对象类型的属性 -->
<bean id="person" class="com.q.spring.demo2.Person">
<property name="name" value="q" />
<property name="shopDao2" ref="shop2" />
</bean> <!-- 3. set 方法注入对象类型的属性 (p名称空间属性注入) -->
<bean id="person" class="com.q.spring.demo2.Person" p:name="q1" p:shopDao2-ref="shop2"></bean> <!-- 3. set 方法注入对象类型的属性 (SpEL 属性注入) -->
<bean id="person" class="com.q.spring.demo2.Person">
<property name="name" value="#{'q1'}"></property>
<property name="shopDao2" value="#{shop2}"></property>
</bean>
// set 方法注入对象类型(需要提供 set 方法)
@Test
public void demo3(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) applicationContext.getBean("person");
System.out.println(person); }
4. p名称空间属性注入
<bean id="person" class="com.q.spring.demo2.Person" p:name="q1" p:shopDao2-ref="shop2"></bean>
5. SpEL 属性注入 (Spring 3.0 之后)
<bean id="shop2" class="com.q.spring.demo2.ShopDao2">
<property name="name" value="#{'q1'}"></property>
<property name="price" value="#{111}"></property>
</bean>
6. 集合类型的注入 ( arrs list set map )
private String[] arrs;
private List<String> list;
private Set<String> set;
private Map<String, String> map;
<bean id="typealls" class="com.q.spring.demo2.typeAlls">
<!-- 数组类型 -->
<property name="arrs">
<list>
<value>a</value>
<value>b</value>
<value>c</value>
</list>
</property> <!-- list集合 -->
<property name="list">
<list>
<value>a1</value>
<value>b1</value>
<value>c1</value>
</list>
</property> <!-- set集合 -->
<property name="set">
<set>
<value>a1</value>
<value>b1</value>
<value>c1</value>
</set>
</property> <!-- map 集合 -->
<property name="map">
<map>
<entry key="b2" value="b2" />
<entry key="b2" value="b2" />
<entry key="b2" value="b2" />
</map>
</property> </bean>
五. 分模块开发的配置
1. 直接在一个xml文件中导入
<import resource="applicationContext.xml" />
2. 在创建 ClassPathXmlApplicationContext 时可传多个参数路径
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml1","applicationContext.xml2");
六. Spring 的 IOC 注解开发
1. 引入约束: 使用注解开发引入 Context 约束
<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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
2. 开启 Spring 的组件扫描
<!-- 配置组件扫描(哪些包下的类使用IOC注解) -->
<context:component-scan base-package="包路径"></context:component-scan>
3. 在类上添加注解
- @Component : 组件
- 装饰一个类,将这个类交给 Spring 管理。
- 这个注解有三个衍生注解: - @Controller : web 层
- @Service : service 层
- @Repository : dao 层
import org.springframework.stereotype.Component; // value 可省略: @Component("shopDao")
@Component(value = "userDao") // 相当于在 <bean id="userDao" class="com.q.spring.demo2.userDemo2" />
public class userDemo2 implements UserDao {
public void save(){ }
}
4. 注解方式设置属性值
注解方式:使用注解方式,可以没有 set 方法。
- 属性如果有 set 方法,需要将属性注入的注解加到 set 方法上。
// 如:
@Value("添加注解")
public void setName(String name){
this.name = name;
}
- 属性如果没有 set 方法,需要将属性注入的注解添加到属性上。
// 如:
@Value("添加注解")
private String name;
5. 属性注入的注解
# 普通属性:
@Value : 设置普通属性的值
# 对象类型属性:
@Autowired : 设置对象类型的属性值。但是按照类型完成属性注入(按照类名的一致)。
- 可以通过 @Qualifier 和 @Autowired 配合使用来修改为按照名称属性注入。
@Resource : 完成对象类型的属性注入,按照名称完成属性注入。 (常用)。
6. Bean 的其他注解
# 生命周期相关注解:
@PostConstruct : 初始化方法
@PreDestroy : 销毁方法
# Bean 作用范围的注解:
@scope : 作用范围
参数:
- singleton : 默认单例
- prototype : 多例
七. Spring 的 AOP 的 XML 开发
1. applocationContext.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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 配置目标对象 :被增强的对象 -->
<bean id="productDao" class="com.q.spring.demo1.ProductDaoImpl" /> <!-- 将切面类交给 Spring 管理 -->
<bean id="myAspect" class="com.q.spring.demo1.MyAspectXml" /> <aop:config>
<!-- 通过AOP的配置完成对目标类产生代理 -->
<aop:pointcut expression="execution(* com.q.spring.demo1.ProductDaoImpl.save(..))" id="pointcut1" />
<aop:pointcut expression="execution(* com.q.spring.demo1.ProductDaoImpl.delete(..))" id="pointcut2" />
<aop:pointcut expression="execution(* com.q.spring.demo1.ProductDaoImpl.update(..))" id="pointcut3" />
<aop:pointcut expression="execution(* com.q.spring.demo1.ProductDaoImpl.find(..))" id="pointcut4" /> <!-- 配置切面 -->
<aop:aspect ref="myAspect">
<!-- 前置通知:获得切入点信息 -->
<aop:before method="checkPri" pointcut-ref="pointcut1" /> <!-- 后置通知 -->
<aop:after-returning method="writeLog" pointcut-ref="pointcut2" returning="result" /> <!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="pointcut3" /> <!-- 异常抛出通知 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex" /> <!-- 最终通知 -->
<aop:after method="after" pointcut-ref="pointcut4" />
</aop:aspect>
</aop:config>
</beans>
2. ProductDao.java 接口文件
package com.q.spring.demo1; public interface ProductDao {
public void save();
public void update();
public String delete();
public void find();
}
3. ProductDaoImpl.java DAO文件
package com.q.spring.demo1; public class ProductDaoImpl implements ProductDao { @Override
public void save() {
System.out.println("save");
} @Override
public void update() {
System.out.println("update");
} @Override
public String delete() {
System.out.println("delete");
return "Delete!!!";
} @Override
public void find() {
System.out.println("find");
// int i = 1/0;
}
}
4. MyAspectXML.java
package com.q.spring.demo1; // 切面类 import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint; public class MyAspectXml { // 前置通知
public void checkPri(JoinPoint joinpoint){
System.out.println("权限校验 "+ joinpoint);
} // 后置通知
public void writeLog(Object result){
System.out.println("日志记录 "+ result);
} // 环绕通知 : 性能监控
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("环绕前通知...");
Object obj = joinPoint.proceed();
System.out.println("环绕后通知...");
return obj;
} // 异常抛出通知
public void afterThrowing(Throwable ex){
System.out.println("异常抛出通知..."+ ex.getMessage());
} // 最终通知:类似于 finally
public void after(){
System.out.println("最终通知...");
}
}
5. 测试文件
package com.q.spring.demo1; import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.annotation.Resource; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo1 { @Resource(name="productDao")
private ProductDao productDao; @Test
public void demo1(){
productDao.save();
productDao.update();
productDao.delete();
productDao.find();
}
}
八. Srping 的 AOP 注解
1. applocationContext.xml 文件
<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"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 在配置文件中开启注解的AOP开发 -->
<aop:aspectj-autoproxy /> <!-- 配置目标类 -->
<bean id="orderDao" class="com.q.spring.demo1.OrderDao" /> <!-- 配置切面类 -->
<bean id="myAspect" class="com.q.spring.demo1.MyAspectAnno" />
</beans>
2. OrderDao.java 文件
package com.q.spring.demo1; public class OrderDao {
public void save(){
System.out.println("save...");
} public void update(){
System.out.println("update...");
} public String delete(){
System.out.println("delete...");
return "Delete!!!";
} public void find(){
System.out.println("find...");
// int i = 1/0;
}
}
3. MyAspectAnno.java 文件
package com.q.spring.demo1; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*; @Aspect
public class MyAspectAnno { // 前置通知
// execution(* com.q.spring.demo1.OrderDao.save(..))
@Before(value = "MyAspectAnno.pointcut1()")
public void befor(){
System.out.println("前置增强");
} // 后置通知
@AfterReturning(value = "MyAspectAnno.pointcut3()", returning = "result")
public void afterReturning(Object result){
System.out.println("后置增强 "+ result);
} // 环绕通知
@Around(value = "MyAspectAnno.pointcut2()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("环绕前增强");
Object obj = joinPoint.proceed();
System.out.println("环绕后增强");
return obj;
} // 异常抛出通知
@AfterThrowing(value = "MyAspectAnno.pointcut4()", throwing = "e")
public void afterThrowing(Throwable e){
System.out.println("异常抛出增强: "+e);
} // 最终通知
@After(value = "MyAspectAnno.pointcut4()")
public void afterThrowing(){
System.out.println("最终增强");
} // 切入点注解
@Pointcut(value = "execution(* com.q.spring.demo1.OrderDao.save(..))")
private void pointcut1(){}
@Pointcut(value = "execution(* com.q.spring.demo1.OrderDao.update(..))")
private void pointcut2(){}
@Pointcut(value = "execution(* com.q.spring.demo1.OrderDao.delete(..))")
private void pointcut3(){}
@Pointcut(value = "execution(* com.q.spring.demo1.OrderDao.find(..))")
private void pointcut4(){}
}
4. SpringDemo1.java 文件
package com.q.spring.demo1; import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.annotation.Resource; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo1 { @Resource(name = "orderDao")
private OrderDao orderDao; @Test
public void demo1(){
orderDao.save();
orderDao.update();
orderDao.delete();
orderDao.find();
} }
九. Spring 的 JDBC 模板
Spring 是一站式框架,有持久层解决方案
1. DBCP 连接池
# 文档..
2. C3P0 连接池
# 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"
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/aop
http://www.springframework.org/schema/aop/spring-aop.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_jdbc" />-->
<!-- <property name="user" value="root" />-->
<!-- <property name="password" value="chaoqi" />-->
<!-- </bean>--> <!-- 引入属性文件 -->
<context:property-placeholder location="classpath:jdbc.properties" /> <!-- 配置C3P0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean> <!-- 配置 Spring 的JDBC的模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
# 增删改查操作
package com.q.jdbc.demo1; import com.q.jdbc.domain.Account;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.annotation.Resource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JdbcDemo2 { @Resource(name = "jdbcTemplate")
private JdbcTemplate jdbcTemplate; // 增
@Test
public void demo1(){
jdbcTemplate.update("insert into account values(null,?,?)","q4",152d);
} // 改
@Test
public void demo2(){
jdbcTemplate.update("update account set name=?, money = ? where id=? ","q1test",11d,2 );
} // 删
@Test
public void demo3(){
jdbcTemplate.update("delete from account where id=? ",2);
} // 查
@Test
public void demo4(){
String name = jdbcTemplate.queryForObject("select name from account where id=?",String.class,3);
System.out.println(name);
} // 统计查询
@Test
public void demo5(){
Long count = jdbcTemplate.queryForObject("select count(*) from account",Long.class);
System.out.println(count);
} // 封装到一个对象中
@Test
public void demo6(){
Account account = jdbcTemplate.queryForObject("select * from account where id = ?", new MyRowMapper(), 3);
System.out.println(account);
} // 查询多条记录
@Test
public void demo7(){
List<Account> list = jdbcTemplate.query("select * from account", new MyRowMapper());
for(Account account : list){
System.out.println(account);
}
} class MyRowMapper implements RowMapper<Account>{ @Override
public Account mapRow(ResultSet res, int rowNum) throws SQLException { Account account = new Account();
account.setId(res.getInt("id"));
account.setName(res.getString("name"));
account.setMoney(res.getDouble("money")); return account;
}
}
}
十. Spring 的事务传播行为
1. 报则保证多个操作在同一个事务中
PROPAGATION_REQUIRED : 默认值,如果A中有事务,使用A中的事务,如果A没有,创建一个新的事务,将操作包含进来。
PROPAGATION_SUPPORTS : 支持事务
,如果A中有事务,使用A中的事务,如果没有,则不使用事务。
PROPAGATION_MANDATORY : 如果A中有事务,使用A中的事务,如果A中没有事务,则抛异常。
2. 保证多个操作不在同一个事务中
PROPAGATION_REQUIRES_NEW : 如果A中有事务,将A的事务挂起(暂停), 创建新事务,只包含自身操作。
如果A中没有事务,则创建一个新事务,包含自身操作
PROPAGATION_NOT_SUPPORTED : 如果A中有事务,将A的事务挂起,不使用事务管理。
PROPAGATION_NEVER : 如果A中有事务,则抛异常。
3. 嵌套式事务
PROPAGATION_NESTED : 嵌套事务,如果A中有事务,按照A的事务执行,执行完毕后,设置一个保存点,执行B中的操作,如果没有异常,执行通过,如果有异常,可以选择回滚到最初始的位置,也可以回滚到保存点。
十一. Spring 声明式事务管理一 (XML)
XML 步骤:
1. 引入 aop 开发包。
2. 配置事务管理器。
3. 配置增强<tx:Advice>
4. 配置aop
# 1. 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/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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 配置 Service -->
<bean id="accountService" class="com.q.tx.demo2.AccountServiceImpl">
<property name="accountDao" ref="accountDao" />
</bean> <!-- 配置 DAO -->
<bean id="accountDao" class="com.q.tx.demo2.AccountDaoImpl">
<property name="dataSource" ref="dataSource" />
</bean> <!-- 配置连接池的JDBC模板 -->
<!-- 引入属性文件 -->
<context:property-placeholder location="classpath:jdbc.properties" /> <!-- 配置C3P0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean> <!-- 配置事务管理 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean> <!-- 配置事务的增强 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" /> <!-- 实际开发中: -->
<!-- <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" />-->
<!-- <tx:method name="update*" propagation="REQUIRED" />-->
<!-- <tx:method name="delete*" propagation="REQUIRED" />-->
<!-- <tx:method name="find*" read-only="true" />-->
</tx:attributes>
</tx:advice> <!-- AOP的配置 -->
<aop:config>
<aop:pointcut id="pointcut1" expression="execution(* com.q.tx.demo2.AccountServiceImpl.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1" />
</aop:config>
</beans>
# jdbc.propertie.xml 文件属性设置
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///spring_jdbc
jdbc.username=root
jdbc.password=chaoqi
# 2. AccountDaoImpl.java 文件
package com.q.tx.demo2; import org.springframework.jdbc.core.support.JdbcDaoSupport; // 转账Dao实现
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao { @Override
public void outMoney(Integer from, Double money) {
this.getJdbcTemplate().update("update account set money = money - ? where id = ?", money, from);
} @Override
public void inMoney(Integer to, Double money) {
this.getJdbcTemplate().update("update account set money = money + ? where id = ?", money, to);
}
}
# 3. AccountServiceImpl.java 文件
package com.q.tx.demo2; // 转账的业务层实现类
public class AccountServiceImpl implements AccountService { // 注入 DAO
private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
} /*
from : 转出账号
to : 转人账号
money : 转账金额
*/ @Override
public void transfer(Integer from, Integer to, Double money) { accountDao.outMoney(from, money);
// int i = 1/0;
accountDao.inMoney(to, money); } }
# 4. 测试文件
package com.q.tx.demo2; // 测试类 import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.annotation.Resource; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:tx2.xml")
public class SpringDemo1 { @Resource(name = "accountService")
private AccountService accountService; @Test
public void demo1(){
accountService.transfer(1,3,100d);
} }
十二. Spring 声明式事务管理二 (注解方式)
注解 步骤:
1. 引入 aop 开发包。
2. 配置事务管理器。
3. 开启注解事务。
4. 在业务层添加注解
# 1. 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/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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 配置 Service -->
<bean id="accountService" class="com.q.tx.demo3.AccountServiceImpl">
<property name="accountDao" ref="accountDao" />
</bean> <!-- 配置 DAO -->
<bean id="accountDao" class="com.q.tx.demo3.AccountDaoImpl">
<property name="dataSource" ref="dataSource" />
</bean> <!-- 配置连接池的JDBC模板 -->
<!-- 引入属性文件 -->
<context:property-placeholder location="classpath:jdbc.properties" /> <!-- 配置C3P0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean> <!-- 配置事务管理器 第一步 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean> <!-- 开启注解事务 第二步 -->
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
# 2. AccountDaoImpl 文件
package com.q.tx.demo3; import org.springframework.jdbc.core.support.JdbcDaoSupport; // 转账Dao实现
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao { @Override
public void outMoney(Integer from, Double money) {
this.getJdbcTemplate().update("update account set money = money - ? where id = ?", money, from);
} @Override
public void inMoney(Integer to, Double money) {
this.getJdbcTemplate().update("update account set money = money + ? where id = ?", money, to);
}
}
# 3. AccountServiceImpl 文件
package com.q.tx.demo3; import org.springframework.transaction.annotation.Transactional; // 转账的业务层实现类
// 第三步 需要在要进行事务操作的类上加 @Transactional
@Transactional
public class AccountServiceImpl implements AccountService { // 注入 DAO
private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
} /*
from : 转出账号
to : 转人账号
money : 转账金额
*/ @Override
public void transfer(Integer from, Integer to, Double money) { accountDao.outMoney(from, money);
// int i = 1/0;
accountDao.inMoney(to, money); } }
# 4. 测试类
package com.q.tx.demo3; // 测试类 import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.annotation.Resource; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:tx3.xml")
public class SpringDemo1 { @Resource(name = "accountService")
private AccountService accountService; @Test
public void demo1(){
accountService.transfer(1,3,100d);
} }
Java - 框架之 Spring的更多相关文章
- java框架篇---spring AOP 实现原理
什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...
- java框架之Spring(2)-注解配置IOC&AOP配置
注解配置IoC 准备 1.要使用注解方式配置 IoC,除了之前引入的基础 jar 包,还需要引入 spring-aop 支持包,如下: 2.在 applicationContext.xml 中引入 c ...
- java框架篇---spring IOC 实现原理
IOC(DI):其实这个Spring架构核心的概念没有这么复杂,更不像有些书上描述的那样晦涩.java程序员都知道:java程序中的每个业务逻辑至少需要两个或以上的对象来协作完成,通常,每个对象在使用 ...
- Java框架之Spring(四)
本文主要讲述在Spring中 1 注解方式装配 2 以自动扫描把组件纳入spring容器中管理 3 面象切面编程-代理的jdk 版实现 4 使用 Cglib 生成代理 5 aop编程的一些概念 6 使 ...
- java框架之Spring(1)-入门
介绍 概述 Spring 是一个开放源代码的设计层面框架,它解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用.Spring 是于 2003 年兴起的一个轻量级的 J ...
- java框架之Spring(4)-Spring整合Hibernate和Struts2
准备 导包 Struts2 导入 Struts2 zip 包解压目录下 'apps/struts-blank.war' 中所有 jar 包,如下: asm-3.3.jar asm-commons-3. ...
- java框架篇---spring hibernate整合
在会使用hibernate 和spring框架后 两个框架的整合就变的相当容易了, 为什么要整合Hibernate?1.使用Spring的IOC功能管理SessionFactory对象 LocalSe ...
- java框架篇---spring aop两种配置方式
第一种:注解配置AOP 注解配置AOP(使用 AspectJ 类库实现的),大致分为三步: 1. 使用注解@Aspect来定义一个切面,在切面中定义切入点(@Pointcut),通知类型(@Befor ...
- java框架篇---spring IOC依赖注入
spring依赖注入的方式有4种 构造方法注入 属性注入 工厂注入 注解注入 下面通过一个实例统一讲解: User.java package com.bjsxt.model; public class ...
随机推荐
- Java开发笔记(一百一十六)采用UDP协议的Socket通信
前面介绍了如何通过Socket接口传输文本与文件,在示例代码中,Socket客户端得先调用connect方法连接服务端,确认双方成功连上后才能继续运行后面的代码,这种确认机制确保客户端与服务端的的确确 ...
- php中的__get和__set方法
1.__get() 作用:当实例化对象调用一个没有定义的属性时,会自动调用__get()方法 当实例化对象调用一个私有或者受保护的属性时,也会调用这个方法,方式类似 结果是:你访问的公开属性:name ...
- SAS学习笔记60 统计SAS实例之T检验
单样本 H0:服从正态分布 P=0.0988>0.05不拒绝H0,服从正态分布 H0:等于140t=-2.14,P=0.0397 P<0.05,拒绝H0,差异有统计学意义 均值x=130. ...
- tkinter python(图形开发界面) 转自:渔单渠
Tkinter模块("Tk 接口")是Python的标准Tk GUI工具包的接口.Tk和Tkinter可以在大多数的Unix平台下使用,同样可以应用在Windows和Macinto ...
- linux BufferedImage.createGraphics()卡住不动
项目应用服务器tomcat7,在开发(windows).测试环境(linux 64bit)均正常.在生产环境(linux 64bit)一直启动不起来,也没有报错. 最终定位问题:执行到buffered ...
- Python之TensorFlow的数据的读取与存储-2
一.我们都知道Python由于GIL的原因导致多线程并不是真正意义上的多线程.但是TensorFlow在做多线程使用的时候是吧GIL锁放开了的.所以TensorFlow是真正意义上的多线程.这里我们主 ...
- ubuntu 迅雷 XwareDesktop
Xinkai/XwareDesktop Ubuntu上编译安装说明 Home Ubuntu上编译安装说明 使用说明 升级到0.12 升级到0.9 发行版支持情况 名 ...
- Ant Design Pro实现导出Excel
react Ant Design ProUI框架导出Excel(只能导出当前列表数据) 插件安装 npm install js-export-excel 安装完成之后开始引入 import Expor ...
- jmeter中assertion的使用
用于检查测试中得到的响应数据等是否符合预期,用以保证性能测试过程中的数据交互与预期一致. 最新版本的3.0jmeter中有13种不同的断言: 1)BeanShell断言:针对sampler中的Bean ...
- echart 人头
<template> <div :class="className"> <div :id="id" class="spi ...