知识点
连接点
Joinpoint
:连接点,即业务层接口里的方法都是连接点
连接什么:连接业务和增强方法(一般是事务控制)中的点
切入点
Potincut
:切入点,即被增强的方法。
所有的切入点都是连接点,反之则不一定成立。
通知
Advice
:通知,增强:是指拦截到Joinpoint
之后所要做的事情,即增强方法的具体实现。
通知的类型:前置通知、后置通知、异常通知、最终通知、环绕通知。
在环绕通知中有明确的嵌入点方法调用。
案例
账户的业务层接口
package cn.luis.service;
public interface IAccountService {
/**
* 模拟保存账户
* 无参无返回值
*/
void saveAccount();
/**
* 模拟更新账户
* @param i 有参无返回值
*/
void updateAccount(int i);
/**
* 模拟删除账户
* @return 无参有返回值
*/
int deleteAccount();
}
账户的业务层实现类
package cn.luis.service.impl;
import cn.luis.service.IAccountService;
public class AccountServiceImpl implements IAccountService{
@Override
public void saveAccount() {
System.out.println("执行了保存");
}
@Override
public void updateAccount(int i) {
System.out.println("执行了更新"+i);
}
@Override
public int deleteAccount() {
System.out.println("执行了删除");
return 0;
}
}
用于记录日志的工具类,它里面提供了公共的代码
package cn.luis.util;
public class Logger {
/**
* 用于在控制台打印日志,计划让其在切入点方法之前执行。(切入点方法就是业务层方法)
*/
public void printLog() {
System.out.println("开始记录日志...");
}
}
Spring基于xml的AOP配置步骤
-
把通知的bean交给spring管理
-
使用
aop:config
标签,表明开始AOP
的配置 -
使用
aop:aspect
标签,表明配置切面属性:
id
:给切面提供一个唯一标识ref
:指定通知类bean的id
-
在
aop:aspect
标签内部使用对应标签来配置通知的类型如,前置通知:
aop:before
method
属性:用于指定logger类中的哪个方法是前置通知pointcut
属性:用于指定切入点表达式,该表达式的含义指的是对业务层中哪些方法增强
配置文件:bean.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: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">
<!--Spring的IOC配置:把service对象配置起来-->
<!--1. 有一个需要增强方法的service,需要加个日志-->
<bean id="accountService" class="cn.luis.service.impl.AccountServiceImpl"></bean>
<!--配置Logger类-->
<!--2. 写了一个日志的通知,它里面有加日志的方法-->
<bean id="logger" class="cn.luis.util.Logger"></bean>
<!--配置AOP-->
<aop:config>
<!--配置切面-->
<!--3. 配置的这个切面引用了我们配置的通知2-->
<aop:aspect id="logAdvice" ref="logger">
<!--配置通知类型、并且建立通知方法和切入点方法的关联-->
<!--4.通知中有一个printlog方法,他要在方法增强前执行,切点指示printlog方法要对saveAccount方法增强-->
<aop:before method="printLog" pointcut="execution( public void cn.luis.service.impl.AccountServiceImpl.saveAccount())"></aop:before>
</aop:aspect>
</aop:config>
</beans>
测试AOP配置
public class AOPTest {
public static void main(String[] args) {
// 1.获取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
// 2.获取对象
IAccountService as = (IAccountService) ac.getBean("accountService");
// 3.执行方法
as.saveAccount();
as.updateAccount(1);
as.deleteAccount();
}
}