SpringAOP
准备工作
- 1.写持久层的接口及实现类
//接口
public interface BankDao {
//存钱
void saveMoney();
//取钱
void sendMoney();
//转账
void transfer();
//贷款
void loan();
}
//实现类
public class BankDaoImpl implements BankDao {
public void saveMoney() {
System.out.println("正在取钱");
}
public void sendMoney() {
System.out.println("正在存钱");
}
public void transfer() {
System.out.println("正在转账");
}
public void loan() {
System.out.println("正在贷款");
}
}
- 2.编写业务接口及实现类
//业务接口
public interface BankService {
//存钱
void saveMoney();
//取钱
void sendMoney();
//转账
void transfer();
//贷款
void loan();
}
//实现类
public class BankServiceImpl implements BankService {
//业务层service调持久层dao
private BankDao bankDao;
public void setBankDao(BankDao bankDao) {
this.bankDao = bankDao;
}
public void saveMoney() {
bankDao.saveMoney();
}
public void sendMoney() {
bankDao.sendMoney();
}
public void transfer() {
bankDao.transfer();
}
public void loan() {
bankDao.loan();
}
}
我们如果要实现这写业务肯定是跟事务离不开关系的
#####我们的流程肯定是
- 1.验证用户
- 2.开启事务
- 3.业务
- 4.提交事务
- 5.写日志
如果要加一个日志功能,就得在业务里面把现有的代码改了
public class BankServiceImpl implements BankService {
//业务层service调持久层dao
private BankDao bankDao;
private AdminCheck adminCheck;
private TransactionManager transactionManager;
private LogInfo logInfo;
public void setAdminCheck(AdminCheck adminCheck) {
this.adminCheck = adminCheck;
}
public void setTransactionManager(TransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public void setLogInfo(LogInfo logInfo) {
this.logInfo = logInfo;
}
public void setBankDao(BankDao bankDao) {
this.bankDao = bankDao;
}
//存钱的业务逻辑
public void saveMoney() {
//验证用户
adminCheck.check();
//开启事务
transactionManager.openTransaction();
//存钱
bankDao.saveMoney();
//写日志
logInfo.writeLog();
//提交事务
transactionManager.commitTransaction();
}
public void sendMoney() {
bankDao.sendMoney();
}
public void transfer() {
bankDao.transfer();
}
public void loan() {
bankDao.loan();
}
}
测试
public class MyTest01 {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
BankService bankService = context.getBean("bankService", BankService.class);
bankService.saveMoney();
}
}
结果
验证用户信息
开启事务
正在取钱
正在写日志
提交事务
但是在企业中,改动原有的业务代码是大忌
Spring中为我们提供了Aop面向切面编程
Aop可以在不改变原来业务代码的情况下,去增加新的功能
要使用AOP得先导入AOP的支持jar包
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
在applicationContext.xml的配置文件头上添加aop的相关约束
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
">
<!--把bean对象交由Spring管理 -->
<bean class="com.lm.utils.AdminCheck" id="adminCheck"/>
<bean class="com.lm.utils.LogInfo" id="logInfo"/>
<bean class="com.lm.utils.TransactionManager" id="transactionManager"/>
<bean class="com.lm.dao.impl.BankDaoImpl" id="bankDao"/>
<bean class="com.lm.service.impl.BankServiceImpl" autowire="byType" id="bankService">
<property name="bankDao" ref="bankDao"/>
</bean>
</beans>
导入的约束都是成对出现的
然后我们就可以开始使用AOP了
<!--aop配置-->
<aop:config>
<!-- aop:pointcut 切入点,expression 表达式 execution(* com.lm.service.impl.*.*(..)) 执行业务逻辑的时候切入
后面长的是你要切入哪里的全限定名前面的是包名 .*.*(..)的第一个*是哪个类 第二个*是哪个方法 (..)是方法的具体内容 -->
<aop:pointcut id="pointCut" expression="execution(* com.lm.service.impl.*.*(..))"/>
<!--前置验证 -->
<aop:aspect ref="adminCheck">
<aop:before method="check" pointcut-ref="pointCut"/>
</aop:aspect>
<!--环绕在业务前后 -->
<aop:aspect ref="transactionManager">
<aop:around method="doPointCut" pointcut-ref="pointCut"/>
</aop:aspect>
<!--后置写日志 -->
<aop:aspect ref="logInfo">
<aop:after method="writeLog" pointcut-ref="pointCut"/>
</aop:aspect>
</aop:config>
测试
验证用户信息
开启事务
正在取钱
正在写日志
提交事务
用了AOP之后同样实现了刚才的结果