Spring_four

2020-12-13 04:52

阅读:411

标签:mono   编程   activemq   strong   toc   initial   解决方案   资源   分层   

Spring_four

基于XML的AOP实现事务控制

坐标xml

  1. org.springframework
  2. spring-context
  3. 5.0.2.RELEASE
  4. org.springframework
  5. spring-test
  6. 5.0.2.RELEASE
  7. commons-dbutils
  8. commons-dbutils
  9. 1.4
  10. mysql
  11. mysql-connector-java
  12. 5.1.6
  13. c3p0
  14. c3p0
  15. 0.9.1.2
  16. junit
  17. junit
  18. 4.12
  19. org.aspectj
  20. aspectjweaver
  21. 1.8.7

技术图片

删除AccountServiceTest测试类上的@Qualifier的注解,不产生代理对象

  1. /**
  2. * 使用Junit单元测试:测试我们的配置
  3. */
  4. @RunWith(SpringJUnit4ClassRunner.class)
  5. @ContextConfiguration(locations = "classpath:applicationContext.xml")
  6. public class AccountServiceTest {
  7. @Autowired
  8. private AccountService as;
  9. @Test
  10. public void testTransfer(){
  11. as.transfer("aaa","bbb",100f);
  12. }
  13. }

此时事务没有控制住


【配置文件】添加spring的aop

applicationContext.xml

  1. xml version="1.0" encoding="UTF-8"?>
  2. xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:aop="http://www.springframework.org/schema/aop"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/aop
  8. http://www.springframework.org/schema/aop/spring-aop.xsd">
  9. id="accountService" class="com.it.service.impl.AccountServiceImpl">
  10. name="accountDao" ref="accountDao">
  11. id="accountDao" class="com.it.dao.impl.AccountDaoImpl">
  12. name="runner" ref="runner">
  13. name="connectionUtils" ref="connectionUtils">
  14. id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
  15. id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  16. name="driverClass" value="com.mysql.jdbc.Driver">
  17. name="jdbcUrl" value="jdbc:mysql://localhost:3306/itcastspring">
  18. name="user" value="root">
  19. name="password" value="root">
  20. id="connectionUtils" class="com.it.utils.ConnectionUtils">
  21. name="dataSource" ref="dataSource">
  22. id="txManager" class="com.it.utils.TransactionManager">
  23. name="connectionUtils" ref="connectionUtils">
  24. id="pc" expression="execution(* com.it.service..*.*(..))">
  25. ref="txManager">
  26. method="beginTransaction" pointcut-ref="pc">
  27. method="commitTransaction" pointcut-ref="pc">
  28. method="rollbackTransaction" pointcut-ref="pc">
  29. method="closeTransaction" pointcut-ref="pc">

【注解】添加spring的aop

可以使用【前置通知】、【后置通知】、【异常通知】、【最终通知】

坐标

  1. org.springframework
  2. spring-context
  3. 5.0.2.RELEASE
  4. org.springframework
  5. spring-test
  6. 5.0.2.RELEASE
  7. commons-dbutils
  8. commons-dbutils
  9. 1.4
  10. mysql
  11. mysql-connector-java
  12. 5.1.6
  13. c3p0
  14. c3p0
  15. 0.9.1.2
  16. junit
  17. junit
  18. 4.12
  19. org.aspectj
  20. aspectjweaver
  21. 1.8.7

配置AccountServiceImpl.java的注解

  1. @Service
  2. public class AccountServiceImpl implements AccountService {
  3. @Autowired
  4. private AccountDao accountDao;
  5. }

配置AccountDaoImpl.java的注解

  1. @Repository
  2. public class AccountDaoImpl implements AccountDao {
  3. @Autowired
  4. private QueryRunner runner;
  5. @Autowired
  6. private ConnectionUtils connectionUtils;
  7. }

配置ConnectionUtils.java的注解

  1. @Component
  2. public class ConnectionUtils {
  3. private ThreadLocalConnection> tl = new ThreadLocalConnection>();
  4. @Autowired
  5. private DataSource dataSource;
  6. }

配置TransactionManager.java的注解

  1. @Component
  2. @Aspect // 切面
  3. public class TransactionManager {
  4. @Autowired
  5. private ConnectionUtils connectionUtils;
  6. @Pointcut(value = "execution(* com.it.service..*.*(..))") // 切入点
  7. public void pc(){};
  8. /**
  9. * 开启事务
  10. */
  11. @Before(value = "pc()")
  12. public void beginTransaction(){
  13. try {
  14. System.out.println("前置通知");
  15. connectionUtils.getThreadConnection().setAutoCommit(false);
  16. }catch (Exception e){
  17. e.printStackTrace();
  18. }
  19. }
  20. /**
  21. * 提交事务
  22. */
  23. @AfterReturning(value = "pc()")
  24. public void commit(){
  25. try {
  26. System.out.println("后置通知");
  27. connectionUtils.getThreadConnection().commit();
  28. }catch (Exception e){
  29. e.printStackTrace();
  30. }
  31. }
  32. /**
  33. * 回滚事务
  34. */
  35. @AfterThrowing(value = "pc()")
  36. public void rollback(){
  37. try {
  38. System.out.println("异常通知");
  39. connectionUtils.getThreadConnection().rollback();
  40. }catch (Exception e){
  41. e.printStackTrace();
  42. }
  43. }
  44. /**
  45. * 释放连接
  46. */
  47. @After(value = "pc()")
  48. public void release(){
  49. try {
  50. System.out.println("最终通知");
  51. connectionUtils.getThreadConnection().close();//把连接还回连接池中
  52. connectionUtils.removeConnection();
  53. }catch (Exception e){
  54. e.printStackTrace();
  55. }
  56. }
  57. }

配置spring容器

配置applicationContext.xml

  1. xml version="1.0" encoding="UTF-8"?>
  2. xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:aop="http://www.springframework.org/schema/aop"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/aop
  9. http://www.springframework.org/schema/aop/spring-aop.xsd
  10. http://www.springframework.org/schema/context
  11. http://www.springframework.org/schema/context/spring-context.xsd">
  12. base-package="com.it">
  13. id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
  14. id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  15. name="driverClass" value="com.mysql.jdbc.Driver">
  16. name="jdbcUrl" value="jdbc:mysql://localhost:3306/itcastspring">
  17. name="user" value="root">
  18. name="password" value="root">

text

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration(locations = "classpath:applicationContext.xml")
  3. public class AccountServiceTest {
  4. @Autowired
  5. private AccountService as;
  6. @Test
  7. public void testTransfer(){
  8. as.transfer("aaa","bbb",100f);
  9. }
  10. }

但是发现,抛出异常。

技术图片

因为注解的方式执行顺序是【前置通知】、【最终通知】、【异常通知】/【后置通知】

技术图片

我们需要使用环绕通知解决问题。

配置TransactionManager.java

  1. @Component
  2. @Aspect
  3. public class TransactionManager {
  4. @Autowired
  5. private ConnectionUtils connectionUtils;
  6. @Pointcut(value = "execution(* com.it.service..*.*(..))")
  7. public void pc(){};
  8. /**
  9. * 开启事务
  10. */
  11. //@Before(value = "pc()")
  12. public void beginTransaction(){
  13. try {
  14. System.out.println("前置通知");
  15. connectionUtils.getThreadConnection().setAutoCommit(false);
  16. }catch (Exception e){
  17. e.printStackTrace();
  18. }
  19. }
  20. /**
  21. * 提交事务
  22. */
  23. //@AfterReturning(value = "pc()")
  24. public void commit(){
  25. try {
  26. System.out.println("后置通知");
  27. connectionUtils.getThreadConnection().commit();
  28. }catch (Exception e){
  29. e.printStackTrace();
  30. }
  31. }
  32. /**
  33. * 回滚事务
  34. */
  35. //@AfterThrowing(value = "pc()")
  36. public void rollback(){
  37. try {
  38. System.out.println("异常通知");
  39. connectionUtils.getThreadConnection().rollback();
  40. }catch (Exception e){
  41. e.printStackTrace();
  42. }
  43. }
  44. /**
  45. * 释放连接
  46. */
  47. //@After(value = "pc()")
  48. public void release(){
  49. try {
  50. System.out.println("最终通知");
  51. connectionUtils.getThreadConnection().close();//把连接还回连接池中
  52. connectionUtils.removeConnection();
  53. }catch (Exception e){
  54. e.printStackTrace();
  55. }
  56. }
  57. @Around(value="pc()")
  58. public Object around(ProceedingJoinPoint joinPoint){
  59. Object returnValue = null;
  60. try {
  61. this.beginTransaction(); // 开启事务
  62. returnValue = joinPoint.proceed(joinPoint.getArgs());
  63. this.commit(); // 提交事务
  64. } catch (Throwable throwable) {
  65. throwable.printStackTrace();
  66. this.rollback(); // 回滚事务
  67. }
  68. finally {
  69. this.release(); // 释放资源
  70. }
  71. return returnValue;
  72. }
  73. }

Spring中的JdbcTemplate

1\dbcTemplate概述

它是spring框架中提供的一个对象,是对原始Jdbc API对象的简单封装。spring框架为我们提供了很多的操作模板类。

操作关系型数据的:

JdbcTemplate (操作JDBC,操作数据库)

HibernateTemplate (操作hibernate,操作数据库)

操作nosql数据库的: RedisTemplate(操作Redis,非关系型数据库)

操作消息队列(MQ)的: JmsTemplate (操作ActiveMQ,消息队列)

* 短信平台

* 邮件平台

操作索引库的:ElasticSearchTemplate(操作ElasticSearch,全文检索)

我们今天的主角在spring-jdbc-5.0.2.RELEASE.jar中,我们在导包的时候,除了要导入这个jar包外,还需要导入一个spring-tx-5.0.2.RELEASE.jar(它是和事务相关的)。


坐标xml

  1. org.springframework
  2. spring-context
  3. 5.0.2.RELEASE
  4. org.springframework
  5. spring-jdbc
  6. 5.0.2.RELEASE
  7. org.springframework
  8. spring-tx
  9. 5.0.2.RELEASE
  10. mysql
  11. mysql-connector-java
  12. 5.1.6

创建类Account.java

  1. /**
  2. * 账户的实体类
  3. */
  4. public class Account implements Serializable {
  5. private Integer id;
  6. private String name;
  7. private Float money;
  8. }

创建类JdbcTemplateDemo1.java

使用spring提供的数据源

  1. /**
  2. * JdbcTemplate的最基本用法
  3. */
  4. public class JdbcTemplateDemo1 {
  5. public static void main(String[] args) {
  6. //准备数据源:spring的内置数据源
  7. DriverManagerDataSource ds = new DriverManagerDataSource();
  8. ds.setDriverClassName("com.mysql.jdbc.Driver");
  9. ds.setUrl("jdbc:mysql://localhost:3306/itcastspring");
  10. ds.setUsername("root");


评论


亲,登录后才可以留言!