1.引入aop相关依赖
<!-- spring-aop依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>6.0.2</version>
</dependency>
<!-- spring aspects依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>6.0.2</version>
</dependency>
2.创建目标资源
①接口
public interface Calculator {
int add(int i,int j);
int sub(int i,int j);
int mul(int i,int j);
int div(int i,int j);
}
②实现类
@Component
public class CalculatorImpl implements Calculator {
@Override
public int add(int i, int j) {
int result = i + j;
System.out.println("方法内部result = " + result);
return result;
}
@Override
public int sub(int i, int j) {
int result = i - j;
System.out.println("方法内部result = " + result);
return result;
}
@Override
public int mul(int i, int j) {
int result = i * j;
System.out.println("方法内部result = " + result);
return result;
}
@Override
public int div(int i, int j) {
int result = i / j;
System.out.println("方法内部result = " + result);
return result;
}
}
3.创建切面类
//切面类
@Aspect//切面类
@Component//ioc容器进行管理
public class LogAspect {
}
配置bean文件
<?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:context="http://www.springframework.org/schema/context"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 开启组件扫描-->
<context:component-scan base-package="com.yogurt.spring6.aop.annoaop"></context:component-scan>
<!-- 开启aspectj自动代理,为目标对象生成代理-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
①切入点
切入点表达式
举例:
前置通知
@Aspect//切面类
@Component//ioc容器进行管理
public class LogAspect {
//设置切入点和通知类型
//切入点表达式:execution(访问修饰符 增强方法返回类型 增强方法所在类全路径.方法名称(方法参数))
//通知类型:
// 前置 @Before(value = "切入点表达式配置切入点")
@Before(value = "execution(public int com.yogurt.spring6.aop.annoaop.CalculatorImpl.*(..))")
public void beforeMethod(){
System.out.println("Logger-->前置通知");
}
}
后置通知
// 后置 @After()
@After(value = "execution(* com.yogurt.spring6.aop.annoaop.CalculatorImpl.*(..))")
public void afterMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();//获取增强方法的名称
System.out.println("Logger-->后置通知,方法名称:" + methodName);
}
返回通知
// 返回 @AfterReturning()
@AfterReturning(value = "execution(* com.yogurt.spring6.aop.annoaop.CalculatorImpl.*(..))",returning = "result")
public void afterReturningMethod(JoinPoint joinPoint,Object result){
String methodName = joinPoint.getSignature().getName();//获取增强方法的名称
System.out.println("Logger-->返回通知,方法名称:" + methodName + ",返回结果:" + result);
}
异常通知
// 异常 @AfterThrowing() 获取到目标方法异常信息
//目标方法出现异常,这个通知执行
@AfterThrowing(value = "execution(* com.yogurt.spring6.aop.annoaop.CalculatorImpl.*(..))",throwing = "ex")
public void afterThrowingMethod(JoinPoint joinPoint,Throwable ex){
String methodName = joinPoint.getSignature().getName();//获取增强方法的名称
System.out.println("Logger-->异常通知,方法名称:" + methodName + ",异常信息:" + ex);
}
此时设置异常才能出现通知:
@Component
public class CalculatorImpl implements Calculator {
@Override
public int add(int i, int j) {
int result = i + j;
System.out.println("方法内部result = " + result);
// //为了测试,模拟异常出现
// int a = 1/0;
return result;
}
}
环绕通知
// 环绕 @Around()
@Around(value = "execution(* com.yogurt.spring6.aop.annoaop.CalculatorImpl.*(..))")
public Object aroundMethod(ProceedingJoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();//获取增强方法的名称
Object[] args = joinPoint.getArgs();
String argString = Arrays.toString(args);
Object result = null;
try{
System.out.println("环绕通知==目标方法之前执行");
//调用目标方法
result = joinPoint.proceed();
System.out.println("环绕通知==目标方法返回值之后执行");
}catch (Throwable throwable){
throwable.printStackTrace();
System.out.println("环绕通知==目标方法出现异常执行");
}finally {
System.out.println("环绕通知==目标方法执行完毕执行");
}
return result;
}
②通知类型
前置 @before()
返回 @AfterReturning()
异常 @AfterThrowing()
后置 @After()
环绕 @Around()
4.测试
public class TestAop {
@Test
public void testAdd(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
Calculator calculator = context.getBean(Calculator.class);
calculator.add(2,3);
}
}