SpringBoot之集成Spring AOP
来源:互联网 发布:足球角球数据统计网站 编辑:程序博客网 时间:2024/05/21 06:37
在开始之前,我们先把需要的jar包添加到工程里。新增Maven依赖如下:
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-aop</artifactId>
- </dependency>
接下来,我们进入正题。这里的涉及的通知类型有:前置通知、后置最终通知、后置返回通知、后置异常通知、环绕通知,下面我们就具体的来看一下怎么在SpringBoot中添加这些通知。首先我们先创建一个Aspect切面类:
- @Component
- @Aspect
- 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;
-
-
-
-
- @RestController
- @RequestMapping("/aop")
- public class AopTestController {
-
- }
前置通知
配置前置通知:
-
-
-
-
- @Before("executeService()")
- public void doBeforeAdvice(JoinPoint joinPoint){
- System.out.println("我是前置通知!!!");
-
- Object[] obj = joinPoint.getArgs();
-
- joinPoint.getThis();
-
- joinPoint.getTarget();
-
- 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);
- if(obj.length > 0) {
- 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){
-
- return "key=: "+key;
- }
- @RequestMapping("/testAfterReturning01.do")
- public Integer testAfterReturning01(Integer key){
-
- return 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){
-
- return 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());
- try {
- Object obj = proceedingJoinPoint.proceed();
- return obj;
- } catch (Throwable throwable) {
- throwable.printStackTrace();
- }
- return null;
- }
Controller对应的请求处理类如下:
- @RequestMapping("/testAroundService.do")
- public String testAroundService(String key){
-
- return "环绕通知:"+key;
- }
当发送请求为:http://localhost:8001/aop/testAroundService.do?key=55553
当发送请求为:http://localhost:8001/aop/testAfter02.do?key=55553&value=855sss时,不符合环绕通知的切入规则,所以环绕通知不会 执行。
完整的AOP配置代码如下:
- package com.zkn.learnspringboot.web.controller;
-
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
-
-
-
- @RestController
- @RequestMapping("/aop")
- 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){
-
- return "key=: "+key;
- }
- @RequestMapping("/testAfterReturning01.do")
- public Integer testAfterReturning01(Integer key){
-
- return 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){
-
- return key;
- }
- @RequestMapping("/testAroundService.do")
- public String testAroundService(String key){
-
- return "环绕通知:"+key;
- }
- }