一、目录结构(AOP原理)

二、代码

1、AccountDao

 1 package cn.bijian.dao;
 2 
 3 import cn.bijian.model.Account;
 4 
 5 import java.util.List;
 6 
 7 public interface AccountDao {
 8     void saveAccount(Account account);
 9 
10     void deleteAccount(Integer id);
11 
12     void updateAccount(Account account);
13 
14     Account findById(Integer id);
15 
16     List<Account> findAll();
17 
18     Account findByName(String name);
19 }

2、AccountDaoImpl

 1 package cn.bijian.dao.impl;
 2 
 3 import cn.bijian.dao.AccountDao;
 4 import cn.bijian.model.Account;
 5 import cn.bijian.utils.ConnectionUtils;
 6 import org.apache.commons.dbutils.QueryRunner;
 7 import org.apache.commons.dbutils.handlers.BeanHandler;
 8 import org.apache.commons.dbutils.handlers.BeanListHandler;
 9 
10 import java.util.List;
11 
12 public class AccountDaoImpl implements AccountDao {
13     private QueryRunner runner;
14     private ConnectionUtils connectionUtils;
15 
16     public void setRunner(QueryRunner runner) {
17         this.runner = runner;
18     }
19 
20     public void setConnectionUtils(ConnectionUtils connectionUtils) {
21         this.connectionUtils = connectionUtils;
22     }
23 
24     @Override
25     public void saveAccount(Account account) {
26         try{
27             runner.update(connectionUtils.getThreadConnection(),"insert into account(name,money) values (?,?)",account.getName(),account.getMoney());
28         }catch (Exception e){
29             throw new RuntimeException(e);
30         }
31     }
32 
33     @Override
34     public void deleteAccount(Integer id) {
35         try{
36             runner.update(connectionUtils.getThreadConnection(),"delete from account where id = ?",id);
37         }catch (Exception e){
38             throw new RuntimeException(e);
39         }
40     }
41 
42     @Override
43     public void updateAccount(Account account) {
44         try{
45             runner.update(connectionUtils.getThreadConnection(),"update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
46         }catch (Exception e){
47             throw new RuntimeException(e);
48         }
49     }
50 
51     @Override
52     public Account findById(Integer id) {
53         try{
54             return runner.query(connectionUtils.getThreadConnection(),"select * from account where id = ?",new BeanHandler<Account>(Account.class),id);
55         }catch (Exception e){
56             throw new RuntimeException(e);
57         }
58     }
59 
60     @Override
61     public List<Account> findAll() {
62         try{
63             return runner.query(connectionUtils.getThreadConnection(),"select * from account",new BeanListHandler<Account>(Account.class));
64         }catch (Exception e){
65             throw new RuntimeException(e);
66         }
67     }
68 
69     @Override
70     public Account findByName(String name) {
71         try{
72             List<Account> accounts = runner.query(connectionUtils.getThreadConnection(),"select * from account where name = ?",new BeanListHandler<Account>(Account.class),name);
73             if (accounts == null || accounts.size()==0){
74                 return null;
75             }
76             if (accounts.size()>1){
77                 throw new RuntimeException("结果集不唯一,数据有问题!");
78             }
79             return accounts.get(0);
80         }catch (Exception e){
81             throw  new RuntimeException(e);
82         }
83     }
84 }

3、BeanFactory

 1 package cn.bijian.factory;
 2 
 3 
 4 
 5 import cn.bijian.service.AccountService;
 6 import cn.bijian.utils.TransactionManager;
 7 
 8 import java.lang.reflect.InvocationHandler;
 9 import java.lang.reflect.Method;
10 import java.lang.reflect.Proxy;
11 
12 /*
13     用于创建Service的代理对象的工厂
14  */
15 public class BeanFactory {
16     private AccountService accountService;
17     private TransactionManager transactionManager;
18 
19     public final void setAccountService(AccountService accountService) {
20         this.accountService = accountService;
21     }
22 
23     public void setTransactionManager(TransactionManager transactionManager) {
24         this.transactionManager = transactionManager;
25     }
26 
27     public  AccountService getAccountService(){
28         AccountService proxyAccountService = (AccountService) Proxy.newProxyInstance(accountService.getClass().getClassLoader(), accountService.getClass().getInterfaces(), new InvocationHandler() {
29             @Override
30             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
31                 Object rtValue = null;
32                 try{
33                     transactionManager.beginTransaction();
34                     //执行操作
35                     rtValue = method.invoke(accountService,args);
36                     transactionManager.commit();
37                 }catch (Exception e){
38                     transactionManager.rollback();
39                     e.printStackTrace();
40                 }finally {
41                     transactionManager.release();
42                 }
43                 return rtValue;
44             }
45         });
46         return proxyAccountService;
47     }

4、Account

 1 package cn.bijian.model;
 2 
 3 public class Account {
 4     private Integer id;
 5     private String name;
 6     private Double money;
 7 
 8     public Integer getId() {
 9         return id;
10     }
11 
12     public void setId(Integer id) {
13         this.id = id;
14     }
15 
16     public String getName() {
17         return name;
18     }
19 
20     public void setName(String name) {
21         this.name = name;
22     }
23 
24     public Double getMoney() {
25         return money;
26     }
27 
28     public void setMoney(Double money) {
29         this.money = money;
30     }
31 
32     @Override
33     public String toString() {
34         return "Account{" +
35                 "id=" + id +
36                 ", name='" + name + '\'' +
37                 ", money=" + money +
38                 '}';
39     }
40 }

5、AccountService

 1 package cn.bijian.service;
 2 
 3 import cn.bijian.model.Account;
 4 
 5 import java.util.List;
 6 
 7 public interface AccountService {
 8     void saveAccount(Account account);
 9 
10     void deleteAccount(Integer id);
11 
12     void updateAccount(Account account);
13 
14     Account findById(Integer id);
15 
16     List<Account> findAll();
17 
18     void transfer(String sourceName,String targetName,Double money);
19 }

6、AccountServiceImpl

 1 package cn.bijian.service.impl;
 2 
 3 import cn.bijian.dao.AccountDao;
 4 import cn.bijian.model.Account;
 5 import cn.bijian.service.AccountService;
 6 
 7 import java.util.List;
 8 
 9 public class AccountServiceImpl implements AccountService {
10     private AccountDao accountDao;
11 
12     public void setAccountDao(AccountDao accountDao) {
13         this.accountDao = accountDao;
14     }
15 
16     @Override
17     public List<Account> findAll() {
18         return accountDao.findAll();
19     }
20 
21     @Override
22     public Account findById(Integer id) {
23         return accountDao.findById(id);
24     }
25 
26     @Override
27     public void saveAccount(Account account) {
28         accountDao.saveAccount(account);
29     }
30 
31     @Override
32     public void deleteAccount(Integer id) {
33         accountDao.deleteAccount(id);
34     }
35 
36     @Override
37     public void updateAccount(Account account) {
38         accountDao.updateAccount(account);
39     }
40 
41     @Override
42     public void transfer(String sourceName, String targetName, Double money) {
43         System.out.println("transfer开始执行!");
44         Account source = accountDao.findByName(sourceName);
45         Account target = accountDao.findByName(targetName);
46         source.setMoney(source.getMoney() - money);
47         target.setMoney(target.getMoney() + money);
48         accountDao.updateAccount(source);
49 //        int i = 1/0;
50         accountDao.updateAccount(target);
51     }
52 }

7、AccountDaoImpl_OLD

  1 package cn.bijian.service.impl;
  2 
  3 import cn.bijian.dao.AccountDao;
  4 import cn.bijian.model.Account;
  5 import cn.bijian.service.AccountService;
  6 import cn.bijian.utils.TransactionManager;
  7 
  8 import java.util.List;
  9 
 10 public class AccountServiceImpl_OLD implements AccountService {
 11     private AccountDao accountDao;
 12     private TransactionManager transactionManager;
 13 
 14     public void setAccountDao(AccountDao accountDao) {
 15         this.accountDao = accountDao;
 16     }
 17 
 18     public void setTransactionManager(TransactionManager transactionManager) {
 19         this.transactionManager = transactionManager;
 20     }
 21 
 22     @Override
 23     public List<Account> findAll() {
 24         List<Account> accounts = null;
 25         try{
 26             transactionManager.beginTransaction();
 27             accounts = accountDao.findAll();
 28             transactionManager.commit();
 29             return accounts;
 30         }catch (Exception e){
 31             transactionManager.rollback();
 32             e.printStackTrace();
 33         }finally {
 34             transactionManager.release();
 35         }
 36         return null;
 37     }
 38 
 39     @Override
 40     public Account findById(Integer id) {
 41         try{
 42             transactionManager.beginTransaction();
 43             Account account = accountDao.findById(id);
 44             transactionManager.commit();
 45             return account;
 46         }catch (Exception e){
 47             transactionManager.rollback();
 48             e.printStackTrace();
 49         }finally {
 50             transactionManager.release();
 51         }
 52         return null;
 53     }
 54 
 55     @Override
 56     public void saveAccount(Account account) {
 57         try{
 58             transactionManager.beginTransaction();
 59             accountDao.saveAccount(account);
 60             transactionManager.commit();
 61         }catch (Exception e){
 62             transactionManager.rollback();
 63             e.printStackTrace();
 64         }finally {
 65             transactionManager.release();
 66         }
 67     }
 68 
 69     @Override
 70     public void deleteAccount(Integer id) {
 71         try{
 72             transactionManager.beginTransaction();
 73             accountDao.deleteAccount(id);
 74             transactionManager.commit();
 75         }catch (Exception e){
 76             transactionManager.rollback();
 77             e.printStackTrace();
 78         }finally {
 79             transactionManager.release();
 80         }
 81     }
 82 
 83     @Override
 84     public void updateAccount(Account account) {
 85         try{
 86             transactionManager.beginTransaction();
 87             accountDao.updateAccount(account);
 88             transactionManager.commit();
 89         }catch (Exception e){
 90             transactionManager.rollback();
 91             e.printStackTrace();
 92         }finally {
 93             transactionManager.release();
 94         }
 95     }
 96 
 97     @Override
 98     public void transfer(String sourceName, String targetName, Double money) {
 99         try{
100             transactionManager.beginTransaction();
101             Account source = accountDao.findByName(sourceName);
102             Account target = accountDao.findByName(targetName);
103             source.setMoney(source.getMoney() - money);
104             target.setMoney(target.getMoney() + money);
105             accountDao.updateAccount(source);
106             int i = 1/0;
107             accountDao.updateAccount(target);
108             transactionManager.commit();
109         }catch (Exception e){
110             transactionManager.rollback();
111             e.printStackTrace();
112         }finally {
113             transactionManager.release();
114         }
115     }
116 }

8、ConnectionUtils

 1 package cn.bijian.utils;
 2 
 3 import javax.sql.DataSource;
 4 import java.sql.Connection;
 5 
 6 public class ConnectionUtils {
 7     private ThreadLocal<Connection> t = new ThreadLocal<Connection>();
 8     private DataSource dataSource;
 9 
10     public void setDataSource(DataSource dataSource) {
11         this.dataSource = dataSource;
12     }
13 
14     public void setT(ThreadLocal<Connection> t) {
15         this.t = t;
16     }
17 
18     //获取当前线程连接
19     public Connection getThreadConnection(){
20         try{
21             Connection conn = t.get();
22             if (conn == null){
23                 conn = dataSource.getConnection();
24                 t.set(conn);
25             }
26             return conn;
27         }catch (Exception e){
28             throw new RuntimeException(e);
29         }
30     }
31     //把连接和线程解绑
32     public void removeConnection(){
33         t.remove();
34     }
35 }

9、TransactionManager

 1 package cn.bijian.utils;
 2 
 3 public class TransactionManager {
 4     private ConnectionUtils connectionUtils;
 5 
 6     public void setConnectionUtils(ConnectionUtils connectionUtils) {
 7         this.connectionUtils = connectionUtils;
 8     }
 9 
10     public void beginTransaction(){
11         try{
12             connectionUtils.getThreadConnection().setAutoCommit(false);
13         }catch (Exception e){
14             e.printStackTrace();
15         }
16     }
17 
18     public void commit(){
19         try{
20             connectionUtils.getThreadConnection().commit();
21         }catch (Exception e){
22             e.printStackTrace();
23         }
24     }
25 
26     public void rollback(){
27         try{
28             connectionUtils.getThreadConnection().rollback();
29         }catch (Exception e){
30             e.printStackTrace();
31         }
32     }
33 
34     public void release(){
35         try{
36             connectionUtils.getThreadConnection().close();  //只是还回池中,并没有关闭连接
37             connectionUtils.removeConnection();
38         }catch (Exception e){
39             e.printStackTrace();
40         }
41     }
42 }

10、bean.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xsi:schemaLocation="http://www.springframework.org/schema/beans
 5         http://www.springframework.org/schema/beans/spring-beans.xsd">
 6 
 7     <bean id="accountDao" class="cn.bijian.dao.impl.AccountDaoImpl">
 8         <property name="runner" ref="runner"></property>
 9         <property name="connectionUtils" ref="connectionUtils"></property>
10     </bean>
11 
12 
13     <!-- AccountServiceImpl_OLD   -->
14 <!--    <bean id="accountService" class="cn.bijian.service.impl.AccountServiceImpl_OLD">-->
15 <!--        <property name="accountDao" ref="accountDao"></property>-->
16 <!--        <property name="transactionManager" ref="transactionManager"></property>-->
17 <!--    </bean>-->
18 
19 
20     <!-- AccountServiceImpl   -->
21     <bean id="accountService" class="cn.bijian.service.impl.AccountServiceImpl">
22         <property name="accountDao" ref="accountDao"></property>
23     </bean>
24     <!--配置代理的service-->
25     <bean id="proxyAccountService" factory-bean="beanFactory" factory-method="getAccountService"></bean>
26     <!--配置beanFactory-->
27     <bean id="beanFactory" class="cn.bijian.factory.BeanFactory">
28         <property name="accountService" ref="accountService"></property>
29         <property name="transactionManager" ref="transactionManager"></property>
30     </bean>
31 
32     <!--配置QueryRunner-->
33     <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype"></bean>
34 
35     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
36         <property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
37         <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring?serverTimezone=UTC"/>
38         <property name="user" value="root"/>
39         <property name="password" value="123456"/>
40     </bean>
41 
42     <!-- 配置Connection的工具类 ConnectionUtils -->
43     <bean id="connectionUtils" class="cn.bijian.utils.ConnectionUtils">
44         <!-- 注入数据源-->
45         <property name="dataSource" ref="dataSource"></property>
46     </bean>
47 
48     <!-- 配置事务管理器-->
49     <bean id="transactionManager" class="cn.bijian.utils.TransactionManager">
50         <property name="connectionUtils" ref="connectionUtils"></property>
51     </bean>
52 
53 </beans>

11、AccountServiceTest

 1 package cn.bijian.test;
 2 
 3 import cn.bijian.service.AccountService;
 4 import org.junit.Test;
 5 import org.junit.runner.RunWith;
 6 import org.springframework.beans.factory.annotation.Autowired;
 7 import org.springframework.test.context.ContextConfiguration;
 8 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 9 
10 @RunWith(SpringJUnit4ClassRunner.class)
11 @ContextConfiguration(locations = "classpath:bean.xml")
12 public class AccountServiceTest {
13     @Autowired
14     private AccountService accountService;
15 
16     @Test
17     public void testTransfer(){
18         accountService.transfer("aaa","bbb",100d);
19     }
20 }

12、AccountServiceTest2

 1 package cn.bijian.test;
 2 
 3 import cn.bijian.service.AccountService;
 4 import org.junit.Test;
 5 import org.junit.runner.RunWith;
 6 import org.springframework.beans.factory.annotation.Autowired;
 7 import org.springframework.beans.factory.annotation.Qualifier;
 8 import org.springframework.test.context.ContextConfiguration;
 9 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
10 
11 @RunWith(SpringJUnit4ClassRunner.class)
12 @ContextConfiguration(locations = "classpath:bean.xml")
13 public class AccountServiceTest2 {
14     @Autowired
15     @Qualifier("proxyAccountService")
16     private AccountService accountService;
17 
18     @Test
19     public void testTransfer(){
20         accountService.transfer("aaa","bbb",100d);
21     }
22 }

 

posted on 2021-11-01 11:24  晨曦生辉耀匕尖  阅读(29)  评论(0编辑  收藏  举报