spring 5种通知

时间:2023-03-10 03:43:02
spring 5种通知

spring 5种通知

方法实现接口

package com.cn.spring.aop.impl;
//加减乘除的接口类
public interface ArithmeticCalculator {
int add(int i, int j);
int sub(int i, int j);
int mul(int i, int j);
int div(int i, int j);
}

接口实现类

package com.cn.spring.aop.impl;

import org.springframework.stereotype.Component;

//实现类
@Component
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
@Override
public int add(int i, int j) {
int result = i + j;
return result;
} @Override
public int sub(int i, int j) {
int result = i - j;
return result;
} @Override
public int mul(int i, int j) {
int result = i * j;
return result;
} @Override
public int div(int i, int j) {
int result = i / j;
return result;
}
}

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: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.cn.spring.aop.impl">
</context:component-scan> <!--使AspjectJ注解起作用:自动为匹配的类生成代理对象-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

通知切面

package com.cn.spring.aop.impl;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component; import java.util.Arrays;
import java.util.List; //把这个类声明为一个切面:首先需要把该类放入到IOC容器中,在声明为一个切面
@Aspect
@Component
public class LoggingAspect {

@Pointcut("execution(** ArithmeticCalculator.*(..))")
public void declareJointPointExpression(){

}
//声明该方法是一个前置通知:在目标方法开始之前执行
//@Before("execution(public int ArithmeticCalculator.*(int, int))")

//前置通知
@Before("declareJointPointExpression()")
public void beforeMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
List<Object> args = Arrays.asList(joinPoint.getArgs());
Object target = joinPoint.getTarget();
System.out.println("The method " + methodName + " begins with " + args + target);
}

//后置通知
@After("execution(** ArithmeticCalculator.*(int, int))")
public void afterMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
System.out.println("The method " + methodName + " ends ");
}
//返回通知,在方法正常结束后执行的方法,可以访问到方法的返回值
@AfterReturning(value="execution(** ArithmeticCalculator.*(int, int))",
returning = "result")
public void afterReturning(JoinPoint joinPoint , Object result){
String methodName = joinPoint.getSignature().getName(); System.out.println("The method " + methodName + " ends with " + result);
}
//异常通知
@AfterThrowing(value="execution(** ArithmeticCalculator.*(int, int))",
throwing = "ex")
public void afterThrowing(Exception ex){ System.out.println(ex);
} } /*
* JoinPoint访问到连接点上下文的信息
* JoinPoint
 java.lang.Object[] getArgs():获取连接点方法运行时的入参列表;
 Signature getSignature() :获取连接点的方法签名对象;
 java.lang.Object getTarget() :获取连接点所在的目标对象;
 java.lang.Object getThis() :获取代理对象本身;
* */

环绕通知类似于动态代理的全过程

如果环绕通知返回100,则结果为100

spring 5种通知

//功能最强大的环绕通知
//ProceedingJoinPoint 类型的参数可以决定是否执行目标方法
@Around("execution(** ArithmeticCalculator.*(..))")
public Object aroundMethod(ProceedingJoinPoint pjd){
Object result = null ;
String methodName = pjd.getSignature().getName(); try {
System.out.println("before");
result = pjd.proceed();
System.out.println("after " + result);
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("Exception " + e);
}
System.out.println("return " + result);
return result;
}