Spring AOP实例
来源:互联网 发布:淘宝美工和室内设计师 编辑:程序博客网 时间:2024/06/05 07:49
功能描述:在一个转账的业务中加入日志记录和校验(用Spring AOP)
创建账户表:
-- ------------------------------ Table structure for account-- ----------------------------DROP TABLE IF EXISTS `account`;CREATE TABLE `account` ( `account_id` char(16) NOT NULL, `account_name` varchar(20) NOT NULL, `currency` varchar(255) NOT NULL COMMENT '币种', `balance` decimal(20,2) NOT NULL COMMENT '余额', `open_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '开户日期', `open_place` varchar(20) NOT NULL DEFAULT '深圳' COMMENT '开户地点', `account_state` enum('03','02','01','00') NOT NULL COMMENT '账户状态', `password` varchar(255) NOT NULL COMMENT '账户密码', PRIMARY KEY (`account_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Records of account-- ----------------------------INSERT INTO `account` VALUES ('6226000098882323', '张三', 'CNY', '533.00', '2017-07-19 09:24:29', '深圳', '01', '123456');INSERT INTO `account` VALUES ('6226000098882929', '李四', 'CNY', '10116.00', '2017-07-19 09:25:52', '深圳', '01', '123456');
项目结构:
jar包:
1.创建账户实体类
package kay.com.entity;import java.math.BigDecimal;import java.util.Date;public class Account { private String accountId; //账户卡号 private String accountName; //账户姓名 private String currency; //币种 private BigDecimal balance; //余额 private Date openTime; //开户时间 private String openPlace; //开户地点 private String accountState; //账户状态 private String password; //账户密码 //getter setter
2.查询账户和转账DAO(这里使用了原始的JDBC)
package kay.com.dao;import java.math.BigDecimal;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import kay.com.dao.AccountDAO;import kay.com.entity.Account;import kay.com.utils.DBUtils;public class AccountDAOImpl implements AccountDAO{ public Account queryAccountById(String accountId){ Connection connection=null; PreparedStatement psmt=null; ResultSet rs=null; Account account=null; String sql="select * from account where account_id = ?"; try { connection=DBUtils.getConnection(); psmt=connection.prepareStatement(sql); psmt.setString(1, accountId); rs= psmt.executeQuery(); while(rs.next()){ account=new Account(); account.setAccountId(rs.getString(1)); account.setAccountName(rs.getString(2)); account.setCurrency(rs.getString(3)); account.setBalance(rs.getBigDecimal(4)); account.setOpenTime(rs.getDate(5)); account.setOpenPlace(rs.getString(6)); account.setAccountState(rs.getString(7)); account.setPassword(rs.getString(8)); } return account; } catch (Exception e) { e.printStackTrace(); }finally{ DBUtils.release(connection, psmt, rs); } return account; } /** * 转账 */ public int transferCheckInOut(String mainAccountId, String outAccountId, BigDecimal checkMoney){ Connection connection=null; PreparedStatement psmt=null; ResultSet rs=null; int count=0; //更新行数 try { Account outAccount=queryAccountById(outAccountId); BigDecimal oldOutBalance= outAccount.getBalance(); Account mainAccount=queryAccountById(mainAccountId); BigDecimal oldMainBalance=mainAccount.getBalance(); connection=DBUtils.getConnection(); connection.setAutoCommit(false); String sql="UPDATE account SET balance=? where account_id=?"; psmt=connection.prepareStatement(sql); //更新主账户 减钱 oldMainBalance=oldMainBalance.subtract(checkMoney); psmt.setBigDecimal(1,oldMainBalance); psmt.setString(2, mainAccountId); count= psmt.executeUpdate(); //更新被转入账户 金额 加钱 oldOutBalance=oldOutBalance.add(checkMoney); psmt.setBigDecimal(1, oldOutBalance); psmt.setString(2, outAccountId); count+=psmt.executeUpdate(); connection.commit(); //提交事物 } catch (Exception e) { try { connection.rollback(); //事务回滚 } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); }finally{ DBUtils.release(connection, psmt, rs); } return count; }}
3.转账Service
package kay.com.service;import java.math.BigDecimal;import org.springframework.beans.factory.annotation.Autowired;import kay.com.dao.AccountDAO;public class AccountServiceImpl implements AccountService{ private AccountDAO accountDAO; public AccountDAO getAccountDAO() { return accountDAO; } public void setAccountDAO(AccountDAO accountDAO) { this.accountDAO = accountDAO; } public int transferCheckInOut(String mainAccountId, String outAccountId, BigDecimal checkMoney) { return accountDAO.transferCheckInOut(mainAccountId, outAccountId, checkMoney); }}
5.日志切面类和验证切面类
模拟日志
package kay.com.aop;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;public class LogAspect { public void doAfter(JoinPoint jp) { System.out.println("日志记录---- doafter方法 : " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName()); } public Object doAround(ProceedingJoinPoint pjp) throws Throwable { long time = System.currentTimeMillis(); Object retVal = pjp.proceed(); time = System.currentTimeMillis() - time; System.out.println("日志记录---- 执行时间: " + time + " ms"); return retVal; } public void doBefore(JoinPoint jp) { System.out.println("日志记录---- before方法: " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName()); Object[] args=jp.getArgs(); //获取参数 System.out.println("日志记录---- 转出账户:"+args[0] +" 转入账户: "+args[1] +" 转出金额:"+ args[2]); } public void doThrowing(JoinPoint jp, Throwable ex) { System.out.println("method " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName() + " throw exception"); System.out.println(ex.getMessage()); } }
模拟验证
package kay.com.aop;import java.math.BigDecimal;import kay.com.dao.AccountDAO;import kay.com.entity.Account;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;public class ValidateAspect { private AccountDAO accountDAO; //注入dao public AccountDAO getAccountDAO() { return accountDAO; } public void setAccountDAO(AccountDAO accountDAO) { this.accountDAO = accountDAO; } public Object doAround(ProceedingJoinPoint pj) throws Throwable { System.out.println("校验检测----:"); Object[] args=pj.getArgs(); Account mainAccount=accountDAO.queryAccountById((String)args[0]); Account outAccount=accountDAO.queryAccountById((String)args[1]); if(mainAccount==null){ System.out.println("账户:"+args[0]+"不存在!转账未执行"); return 0; }else if(outAccount==null){ System.out.println("转入账户:"+args[1]+"不存在!转账未执行"); return 0; } BigDecimal checkMoney=(BigDecimal)args[2]; BigDecimal mainBalance=mainAccount.getBalance(); if(checkMoney.compareTo(mainBalance)>0){ System.out.println("余额不足,无法转出"); return 0; }else { System.out.println("无异常"); } Object retVal = pj.proceed(); return retVal; } public void doThrowing(JoinPoint jp, Throwable ex) { System.out.println("method " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName() + " throw exception"); System.out.println(ex.getMessage()); } }
6.spring配置
<?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"> <aop:config> <!-- 日志切面 --> <aop:aspect id="logAsp" ref="logAspect"> <aop:pointcut id="businessService" expression="execution(* kay.com.service.*.transferCheckInOut(..))" /> <aop:before pointcut-ref="businessService" method="doBefore"/> <aop:after pointcut-ref="businessService" method="doAfter"/> <aop:around pointcut-ref="businessService" method="doAround"/> <aop:after-throwing pointcut-ref="businessService" method="doThrowing" throwing="ex"/> </aop:aspect> <!-- 验证切面 --> <aop:aspect id="validateAsp" ref="validateAspect"> <aop:pointcut expression="execution(* kay.com.service.*.*(..))" id="validateService"/> <aop:around pointcut-ref="validateService" method="doAround"/> </aop:aspect> </aop:config> <bean id="logAspect" class="kay.com.aop.LogAspect"></bean> <!-- 注入一个dao对象 --> <bean id="validateAspect" class="kay.com.aop.ValidateAspect"> <property name="accountDAO" ref="accountDAO"></property> </bean> <!-- service的实例 --> <bean id="myservice" class="kay.com.service.AccountServiceImpl"> <property name="accountDAO" ref="accountDAO"></property> </bean> <bean id="accountDAO" class="kay.com.dao.AccountDAOImpl"></bean></beans>
7.MainTest
package kay.com;import java.math.BigDecimal;import kay.com.service.AccountService;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class MainTest { public static void main(String[] args) { ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml"); AccountService accountService=(AccountService) context.getBean("myservice"); //余额不足时 //accountService.transferCheckInOut("6226000098882323", "6226000098882929", new BigDecimal("1000.00")); //账户不存在时 accountService.transferCheckInOut("6226000098882321", "6226000098882929", new BigDecimal("200.00")); }}
测试结果
阅读全文
1 0
- Spring AOP 入门实例
- Spring AOP 入门实例
- Spring AOP实例
- Spring AOP 实例
- Spring aop使用实例
- Spring AOP 简单实例
- spring aop 简单实例
- Spring 2.5 AOP 实例
- Spring AOP 实例
- spring AOP 入门实例
- Spring的AOP实例
- Spring Aop实例
- Spring之AOP实例
- Spring 传统AOP实例
- Spring.Net AOP实例
- Spring Aop完整实例
- Spring AOP实例
- Spring AOP 实例2
- HDU 5361(最短路+并查集优化)
- 导入一个AndroidStudio工程作为一个Library Module
- 【LeetCode】500. Keyboard Row
- 洛谷 P3369 【模板】普通平衡树(Treap/SBT)
- Win10 系统时间错误
- Spring AOP实例
- 分配并注册主次设备号
- Maven Tomcat8+ 实现自动化部署
- python爬虫利器-request库
- java.io.Serializable浅析
- 快速入门shell脚本编写(四)
- C++动态内存管理
- C语言基础-复合类型数据,编译相关,关键字,位运算,内存管理,gdb调试
- 将图片网址url转化为bitmap