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 ...
随机推荐
- Delphi百度语音【支持语音识别和语音合成】
作者QQ:(648437169) 点击下载➨百度语音 语音识别api文档 语音合成api文档 [Delphi 百度语音]支持获取 Access Token.语音识别.语 ...
- python模块知识四 包和logging日志
11.包 包:文件夹下具有__init__.py文件就是一个包,包用来管理多个模块 包的结构如下: bake ├── __init__.py ├── api ├── __init__.py ├── p ...
- Android--ScrollView边界回弹效果
/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Versi ...
- AQS(AbstractQueuedSynchronizer)
AbstractQueuedSynchronizer 是一个锁框架.实现的原理(大概): 1.关于重入锁方面的实现,参考(手写一个可重入锁). 2.关于公平锁方面的实现,使用双链表的形式,进行公平锁的 ...
- [BZOJ2739]最远点(DP+分治+决策单调性)
根据旋转卡壳,当逆时针遍历点时,相应的最远点也逆时针转动,满足决策单调性.于是倍长成链,分治优化DP即可,复杂度O(n^2). #include<cstdio> #include<a ...
- 同一个Tomcat部署多个springboot项目问题
2018-12-13 10:37:21,412 ERROR [localhost-startStop-2] c.a.d.s.DruidDataSourceStatManager [DruidDataS ...
- OC与swift相互调用
一.OC调用swift文件 二.swift调用OC文件 三.注意和总结 添加: 四.自定义桥接文件 一.OC调用swift文件 在OC项目中创建一个swift文件的时候,Xcode 会提示 需要创建一 ...
- shell 字符串截取表达式
${var#str} 从左向右匹配,非贪婪匹配,截取并保留右边的内容 txt='123456abc123456' echo ${txt#*34} # 56abc123456 ${var##str} 从 ...
- RedisCluster的rename机制失败报错,解决又是数据倾斜问题
需求说明:spring session中的用户session更新是更新key的名字,所以对于key的操作时需要用newkey 替换oldkey value值只允许存在一个,这里用到rename就很合适 ...
- go语言 goquery爬虫
goquery 类似ruby的gem nokogiri goquery的选择器功能很强大,很好用.地址:https://github.com/PuerkitoBio/goquery 这是一个糗百首 ...