本文共 10755 字,大约阅读时间需要 35 分钟。
在开始之前,我们先把需要的jar包添加到工程里。新增Maven依赖如下:
-
-
<groupId>org.springframework.boot
</groupId> -
<artifactId>spring-boot-starter-aop
</artifactId> -
接下来,我们进入正题。这里的涉及的通知类型有:前置通知、后置最终通知、后置返回通知、后置异常通知、环绕通知,下面我们就具体的来看一下怎么在SpringBoot中添加这些通知。
-
-
-
public class WebControllerAop {
-
-
指定切点:
-
-
@Pointcut(
"execution(* com.zkn.learnspringboot.web.controller..*.*(..))")
-
public void executeService(){
-
-
接着我们再创建一个Controller请求处理类:
-
package com.zkn.learnspringboot.web.controller;
-
-
import org.springframework.web.bind.annotation.RequestMapping;
-
import org.springframework.web.bind.annotation.RestController;
-
-
-
-
-
-
-
public class AopTestController {
-
-
前置通知
-
-
-
-
-
@Before(
"executeService()")
-
public void doBeforeAdvice(JoinPoint joinPoint){
-
System.out.println(
"我是前置通知!!!");
-
-
Object[] obj = joinPoint.getArgs();
-
-
-
-
-
-
Signature signature = joinPoint.getSignature();
-
-
System.out.println(signature.getName());
-
-
System.out.println(signature.getDeclaringTypeName());
-
-
signature.getDeclaringType();
-
-
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
-
-
HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
-
-
-
Enumeration<String> enumeration = request.getParameterNames();
-
Map<String,String> parameterMap = Maps.newHashMap();
-
while (enumeration.hasMoreElements()){
-
String parameter = enumeration.nextElement();
-
parameterMap.put(parameter,request.getParameter(parameter));
-
-
String str = JSON.toJSONString(parameterMap);
-
-
System.out.println(
"请求的参数信息为:"+str);
-
-
注意:这里用到了JoinPoint和RequestContextHolder。通过JoinPoint可以获得通知的签名信息,如目标方法名、目标方法参数信息等。通过RequestContextHolder来获取请求信息,Session信息。
接下来我们在Controller类里添加一个请求处理方法来测试一下前置通知:
-
@RequestMapping(
"/testBeforeService.do")
-
public String testBeforeService(String key,String value){
-
-
return "key="+key+
" value="+value;
-
前置通知拦截结果如下所示:
后置返回通知
配置后置返回通知的代码如下:
-
-
-
-
-
-
-
-
-
-
@AfterReturning(value =
"execution(* com.zkn.learnspringboot.web.controller..*.*(..))",returning =
"keys")
-
public void doAfterReturningAdvice1(JoinPoint joinPoint,Object keys){
-
-
System.out.println(
"第一个后置返回通知的返回值:"+keys);
-
-
-
@AfterReturning(value =
"execution(* com.zkn.learnspringboot.web.controller..*.*(..))",returning =
"keys",argNames =
"keys")
-
public void doAfterReturningAdvice2(String keys){
-
-
System.out.println(
"第二个后置返回通知的返回值:"+keys);
-
Controller里添加响应的请求处理信息来测试后置返回通知:
-
@RequestMapping(
"/testAfterReturning.do")
-
public String testAfterReturning(String key){
-
-
-
-
@RequestMapping(
"/testAfterReturning01.do")
-
public Integer testAfterReturning01(Integer key){
-
-
-
当发送请求为:http://localhost:8001/aop/testAfterReturning.do?key=testsss&value=855sss时,处理结果如图所示:
当发送请求为:http://localhost:8001/aop/testAfterReturning01.do?key=55553&value=855sss时,处理结果如图所示:
后置异常通知
-
-
-
-
-
-
-
-
-
@AfterThrowing(value =
"executeService()",throwing =
"exception")
-
public void doAfterThrowingAdvice(JoinPoint joinPoint,Throwable exception){
-
-
System.out.println(joinPoint.getSignature().getName());
-
if(exception
instanceof NullPointerException){
-
System.out.println(
"发生了空指针异常!!!!!");
-
-
Controller里配置响应的请求处理类:
-
@RequestMapping(
"/testAfterThrowing.do")
-
public String testAfterThrowing(String key){
-
-
throw new NullPointerException();
-
后置异常通知方法的处理结果如下所示:
后置最终通知
-
-
-
-
-
@After(
"executeService()")
-
public void doAfterAdvice(JoinPoint joinPoint){
-
-
System.out.println(
"后置通知执行了!!!!");
-
Controller类配置相应的请求处理类:
-
@RequestMapping(
"/testAfter.do")
-
public String testAfter(String key){
-
-
throw new NullPointerException();
-
-
@RequestMapping(
"/testAfter02.do")
-
public String testAfter02(String key){
-
-
-
当发送请求为:http://localhost:8001/aop/testAfter.do?key=55553&value=855sss
当发送请求为:http://localhost:8001/aop/testAfter02.do?key=55553&value=855sss
环绕通知
-
-
-
-
-
-
@Around(
"execution(* com.zkn.learnspringboot.web.controller..*.testAround*(..))")
-
public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
-
System.out.println(
"环绕通知的目标方法名:"+proceedingJoinPoint.getSignature().getName());
-
-
Object obj = proceedingJoinPoint.proceed();
-
-
}
catch (Throwable throwable) {
-
throwable.printStackTrace();
-
-
-
-
@RequestMapping(
"/testAroundService.do")
-
public String testAroundService(String key){
-
-
-
当发送请求为:http://localhost:8001/aop/testAroundService.do?key=55553
当发送请求为:http://localhost:8001/aop/testAfter02.do?key=55553&value=855sss时,不符合环绕通知的切入规则,所以环绕通知不会 执行。
-
package com.zkn.learnspringboot.aop;
-
-
import com.alibaba.fastjson.JSON;
-
import com.google.common.collect.Maps;
-
import org.aspectj.lang.JoinPoint;
-
import org.aspectj.lang.ProceedingJoinPoint;
-
import org.aspectj.lang.Signature;
-
import org.aspectj.lang.annotation.*;
-
import org.springframework.stereotype.Component;
-
import org.springframework.web.context.request.RequestAttributes;
-
import org.springframework.web.context.request.RequestContextHolder;
-
-
import javax.servlet.http.HttpServletRequest;
-
import javax.servlet.http.HttpSession;
-
import java.util.Enumeration;
-
-
-
-
-
-
-
-
public class WebControllerAop {
-
-
-
@Pointcut(
"execution(* com.zkn.learnspringboot.web.controller..*.*(..))")
-
public void executeService(){
-
-
-
-
-
-
-
-
@Before(
"executeService()")
-
public void doBeforeAdvice(JoinPoint joinPoint){
-
System.out.println(
"我是前置通知!!!");
-
-
Object[] obj = joinPoint.getArgs();
-
-
-
-
-
-
Signature signature = joinPoint.getSignature();
-
-
System.out.println(signature.getName());
-
-
System.out.println(signature.getDeclaringTypeName());
-
-
signature.getDeclaringType();
-
-
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
-
-
HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
-
-
-
Enumeration<String> enumeration = request.getParameterNames();
-
Map<String,String> parameterMap = Maps.newHashMap();
-
while (enumeration.hasMoreElements()){
-
String parameter = enumeration.nextElement();
-
parameterMap.put(parameter,request.getParameter(parameter));
-
-
String str = JSON.toJSONString(parameterMap);
-
-
System.out.println(
"请求的参数信息为:"+str);
-
-
-
-
-
-
-
-
-
-
-
-
-
@AfterReturning(value =
"execution(* com.zkn.learnspringboot.web.controller..*.*(..))",returning =
"keys")
-
public void doAfterReturningAdvice1(JoinPoint joinPoint,Object keys){
-
-
System.out.println(
"第一个后置返回通知的返回值:"+keys);
-
-
-
@AfterReturning(value =
"execution(* com.zkn.learnspringboot.web.controller..*.*(..))",returning =
"keys",argNames =
"keys")
-
public void doAfterReturningAdvice2(String keys){
-
-
System.out.println(
"第二个后置返回通知的返回值:"+keys);
-
-
-
-
-
-
-
-
-
-
-
@AfterThrowing(value =
"executeService()",throwing =
"exception")
-
public void doAfterThrowingAdvice(JoinPoint joinPoint,Throwable exception){
-
-
System.out.println(joinPoint.getSignature().getName());
-
if(exception
instanceof NullPointerException){
-
System.out.println(
"发生了空指针异常!!!!!");
-
-
-
-
-
-
-
-
@After(
"executeService()")
-
public void doAfterAdvice(JoinPoint joinPoint){
-
-
System.out.println(
"后置通知执行了!!!!");
-
-
-
-
-
-
-
-
@Around(
"execution(* com.zkn.learnspringboot.web.controller..*.testAround*(..))")
-
public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
-
System.out.println(
"环绕通知的目标方法名:"+proceedingJoinPoint.getSignature().getName());
-
-
Object obj = proceedingJoinPoint.proceed();
-
-
}
catch (Throwable throwable) {
-
throwable.printStackTrace();
-
-
-
-
完整的Controller类代码如下:
-
package com.zkn.learnspringboot.web.controller;
-
-
import org.springframework.web.bind.annotation.RequestMapping;
-
import org.springframework.web.bind.annotation.RestController;
-
-
-
-
-
-
-
public class AopTestController {
-
-
@RequestMapping(
"/testBeforeService.do")
-
public String testBeforeService(String key,String value){
-
-
return "key="+key+
" value="+value;
-
-
@RequestMapping(
"/testAfterReturning.do")
-
public String testAfterReturning(String key){
-
-
-
-
@RequestMapping(
"/testAfterReturning01.do")
-
public Integer testAfterReturning01(Integer key){
-
-
-
-
@RequestMapping(
"/testAfterThrowing.do")
-
public String testAfterThrowing(String key){
-
-
throw new NullPointerException();
-
-
@RequestMapping(
"/testAfter.do")
-
public String testAfter(String key){
-
-
throw new NullPointerException();
-
-
@RequestMapping(
"/testAfter02.do")
-
public String testAfter02(String key){
-
-
-
-
@RequestMapping(
"/testAroundService.do")
-
public String testAroundService(String key){
-
-
-
-