Java56spring:事务控制
Posted 码农编程录
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java56spring:事务控制相关的知识,希望对你有一定的参考价值。
1.AOP半注解半xml
//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">
<!-- 开启IOC注解扫描的包 -->
<context:component-scan base-package="com.itheima"></context:component-scan>
<!-- 开启注解AOP -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
package com.itheima.service;
public interface UserService {
public void findUserById();
}
package com.itheima.service.impl;
import com.itheima.service.UserService;
import org.springframework.stereotype.Service;
@Service("userService")
public class UserServiceImpl implements UserService {
@Override
public void findUserById() {
System.out.println("根据用户的id查询用户的信息");
//int i = 1/0;
}
}
package com.itheima.utils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component // 当前增强类装配到spring容器
@Aspect // 声明当前类是一个切面类
public class LogUtils {
/**
* xml中开启aop注解方式:
* <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
* 在通知类上添加
* @Aspect 声明当前类是一个切面类
* @Component //当前增强类装配到spring容器
*
* @Before : 配置前置通知
* @AfterReturning: 配置后置通知
* @After: 配置最终通知
* @Around : 配置环绕通知
* @AfterThrowing: 配置异常通知
*
* 注解方式抽取切入点:
* 1.声明一个空实现的方法:pt1()
* 2.在方法上添加@Pointcut注解,value属性值就是切入点的AspectJ表达式
* 3.方法名就是切入点的 id
*/
//@Before("execution(* com.itheima.service.impl.*.*(..))")
public void printLog(){
System.out.println("前置通知");
}
//@AfterReturning("execution(* com.itheima.service.impl.*.*(..))")
public void printLog2(){
System.out.println("后置通知");
}
//@AfterThrowing("execution(* com.itheima.service.impl.*.*(..))")
public void printLog3(){
System.out.println("异常通知");
}
@Pointcut("execution(* com.itheima.service.impl.*.*(..))")
public void pt1(){
}
@Around("pt1()")
public void printLog4(ProceedingJoinPoint point){
try {
System.out.println("自定义环绕通知,开启事务。");
//调用原有功能的方法。
point.proceed();
System.out.println("自定义环绕通知,提交事务");
} catch (Throwable throwable) {
System.out.println("自定义环绕通知,回滚事务");
throwable.printStackTrace();
}finally {
System.out.println("自定义环绕通知,释放资源");
}
}
}
package com.itheima.service;
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 javax.swing.*;
import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void findUserById() {
userService.findUserById();
}
}
2.纯注解开发
package com.itheima.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.itheima")
public class SpringConfig {
/**
* 开发步骤:
* 1. @Configuration 标注当前类是一个配置类
* 2.@ComponentScan 开启注解扫描(ioc)
* 3.@EnableAspectJAutoProxy 开启注解aop即可
*/
}
package com.itheima.service;
import com.itheima.config.SpringConfig;
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 javax.swing.*;
import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void findUserById() {
userService.findUserById();
}
}
3.JdbcTemplate
3.1 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itheima</groupId>
<artifactId>spring_day04_01</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<!-- java编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--IOC-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!--jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!-- 事务相关的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!-- aop 相关依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
</dependencies>
</project>
<?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: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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
</bean>
<bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl">
<!-- <property name="jdbcTemplate" ref="jdbcTemplate"></property>-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
</bean>-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driverClass}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="url" value="${jdbc.url}"></property>
</bean>
<!-- spring事务的配置步骤
1.在applicationContext.xml中配置事务管理器的bean
2.配置事务的策略
3.配置事务的aop
-->
<!--
声明对于jdbc进行事务管理的 事务管理器对象
id建议叫做 transactionManager,如果不叫这个名字,我们配置策略是,需要指定事务管理器对象的名字
-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--
配置spring事务的策略
tx:advice:声明开始配置事务的策略
id:当前策略的唯一标识
transaction-manager: 指定事务管理器对象。默认值为transactionManager
-->
<tx:advice id="tx1" >
<!-- 声明具体的策略 -->
<tx:attributes>
<!--
tx:method : 指定对于哪些方法进行事务的管理
name:方法名的表达式
read-only: 事务是否只读,默认是false
timeout:超时时间,默认为-1,永不超时。
isolation: 事务的隔离级别,默认采用数据库默认的隔离级别
propagation: 事务的传播行为
rollback-for="": 针对指定的异常进行回滚
no-rollback-for="": 针对指定的异常不进行回滚
-->
<tx:method name="*" />
<!-- <tx:method name="select*" read-only="true"/>-->
</tx:attributes>
</tx:advice>
<!-- 配置事务的aop
AspectJ 表达式的语法 修饰符 返回值 包名.类型.方法名()
-->
<aop:config>
<aop:pointcut id="pt1" expression="execution(* com.itheima.service.impl.*.*(..))"></aop:pointcut>
<!--
advice-ref="tx1":使用哪个策略
pointcut-ref="pt1" : 事务切入到哪个切入点
-->
<aop:advisor advice-ref="tx1" pointcut-ref="pt1"></aop:advisor>
</aop:config>
</beans>
//jdbc.properties
jdbc.username=root
jdbc.password=root
jdbc.url=jdbc:mysql://localhost:3306/spring_day02
jdbc.driverClass=com.mysql.jdbc.Driver
3.2 domain
package com.itheima.domain;
public class Account {
private int id;
private String name;
private double money;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\\'' +
", money=" + money +
'}';
}
}
以上是关于Java56spring:事务控制的主要内容,如果未能解决你的问题,请参考以下文章
Java实战之03Spring-05Spring中的事务控制(基于AOP)