使用 XML 配置 Spring AOP的通知(后置、环绕、正常返回、异常返回)
1 准备工作
1.1 创建EmpService接口
package com.service;
public interface EmpService {
void add();
String find();
void delete();
}
1.2 创建EmpService接口的实现类EmpServiceImpl
package com.service.impl;
import com.service.EmpService;
public class EmpServiceImpl implements EmpService {
@Override
public void add() {
System.out.println("添加员工");
}
@Override
public String find() {
System.out.println("查询员工");
return "xxx员工";
}
@Override
public void delete() {
/*事务不能try...catch 报错一定要回滚.不报错就应该提交事务*/
System.out.println(1/0);
}
}
1.3 注意:接口和实现类需要满足以下位置关系
1.4 导入AOP实现依赖
<!--AOP实现依赖-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
</dependency>
1.5 创建切面类
package com.aop;
import org.aspectj.lang.JoinPoint;
//切面类(增强类) 每个方法中重复要做的事情 重复的代码写这里
public class Aop {
}
1.6 在主配置文件spring.xml中创建组件
<bean id="aop" class="com.aop.Aop"></bean>
<bean id="es" class="com.service.impl.EmpServiceImpl"></bean>
1.7 在主配置文件spring.xml中进行切入点的配置(告知切入的范围是什么)
<aop:config>
<aop:pointcut id="ppp" expression="execution(* com.service.impl.*.*(..))"/>
</aop:config>
2 后置通知
2.1 创建后置通知时需要执行的方法
2.1.1 创建的位置
切面类aop中
2.1.2 方法的内容
public void b(){
//拿不到返回值,业务执行之后
System.out.println("---- --执行了后置方法--------");
}
2.2 配置后置通知
2.2.1 配置的位置
aop:aspect标签中,其中ref属性是切面类(组件)的id
2.2.2 具体配置如下所示
<aop:aspect ref="aop">
<aop:after method="b" pointcut-ref="ppp"></aop:after>
</aop:aspect>
2.2.3 配置分析
其中after代表后置,method是后置通知时需要执行的方法的的方法名,pointcut-ref为切入点
2.3 测试代码
import com.service.EmpService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
EmpService es = ac.getBean(EmpService.class);
es.add();
System.out.println("------");
}
}
2.4测试代码运行截图
3 环绕通知
3.1 创建环绕通知时需要执行的方法
3.1.1 创建的位置
切面类aop中
3.1.2 方法的内容
public void c(ProceedingJoinPoint pjp) throws Throwable {
/*调用目标方法,拿到返回值 包含前置和后置*/
//可以得到方法的运行时间
System.out.println("环绕前");
Object obj = pjp.proceed();
//在proceed方法执行之后的都是原方法执行完成之后的逻辑
String name = pjp.getSignature().getName();
System.out.println("环绕后"+name+"方法返回值: "+obj);
}
3.2 配置环绕通知
3.2.1 配置的位置
aop:aspect标签中,其中ref属性是切面类(组件)的id
3.2.2 具体配置如下所示
<aop:aspect ref="aop">
<aop:around method="c" pointcut-ref="ppp"></aop:around>
</aop:aspect>
3.2.3 配置分析
其中around代表环绕,method是环绕通知时需要执行的方法的的方法名,pointcut-ref为切入点
3.3 测试代码
import com.service.EmpService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
EmpService es = ac.getBean(EmpService.class);
es.add();
System.out.println("------");
}
}
3.4测试代码运行截图
4 正常返回通知
4.1 正常返回通知时需要执行的方法
4.1.1 创建的位置
切面类aop中
4.1.2 方法的内容
public void d(JoinPoint jp,Object obj){
//目标方法不报错就进入,多个形式参数时obj必须是最后一个参数
String name = jp.getSignature().getName();
System.out.println(name+"方法未报错 返回值为:"+obj);
}
4.2 配置正常返回通知
4.2.1 配置的位置
aop:aspect标签中,其中ref属性是切面类(组件)的id
4.2.2 具体配置如下所示
<aop:aspect ref="aop">
<aop:after-returning method="d" pointcut-ref="ppp" returning="obj"></aop:after-returning>
</aop:aspect>
4.2.3 配置分析
其中after-returning代表正常返回,method是配置正常返回通知时需要执行的方法的的方法名,returning是方法执行后的返回值
4.3 测试代码
import com.service.EmpService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
EmpService es = ac.getBean(EmpService.class);
es.find();
System.out.println("------");
}
}
4.4测试代码运行截图
5 异常返回通知
5.1 异常返回通知时需要执行的方法
5.1.1 创建的位置
切面类aop中
5.1.2 方法的内容
//目标方法错误就进入
public void e(JoinPoint jp,Exception ex){
//目标方法不报错就进入,多个新参obj必须最后一个参数
String name = jp.getSignature().getName();
System.out.println(name+"方法报错异常信息为:"+ex.getMessage());
}
5.2 配置异常返回通知
5.2.1 配置的位置
aop:aspect标签中,其中ref属性是切面类(组件)的id
5.2.2 具体配置如下所示
<aop:aspect ref="aop">
<aop:after-throwing method="e" pointcut-ref="ppp" throwing="ex"></aop:after-throwing>
</aop:aspect>
5.2.3 配置分析
其中after-throwing代表异常返回,method是配置异常返回通知时需要执行的方法的的方法名,throwing是方法报错时的返回信息
5.3 测试代码
import com.service.EmpService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
EmpService es = ac.getBean(EmpService.class);
es.delete();
System.out.println("------");
}
}