0%

SpringBoot面向切面AOP

你要成为想象中的样子,这件事,一步也不能退。

概述

AOP是动态代理思想实现的典型例子,一般在项目中主要是做一些统一性的日志或者错误的处理。

实现

依赖

1
2
3
4
5
 <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>1.5.4.RELEASE</version>
</dependency>

代码

1
2
3
4
5
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Action {
String value() default "" ;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@Component
@Aspect
public class LogAspect {

// 注解式切点(侵入式,需要在方法上添加自定义注解)
@Pointcut("@annotation(com.stack.config.annotation.Action)")
public void logPointCut (){
}

// 定义切点表达式(非侵入式,一般企业开发更推荐使用这样的方式)
@Pointcut("execution(* com.stack.config.controller.TaskController.*(..))")
public void controllerPointCut() {
}

// 注解式环绕方法
@Around("logPointCut()")
public Object around (ProceedingJoinPoint point) throws Throwable {
Object result = null ;
try{
System.out.println("方法执行开始。。。");
// 获取方法名
Signature signature = point.getSignature();
System.out.println("方法名:"+signature.getName());
Object[] args = point.getArgs();
System.out.println("请求参数:"+ JSON.toJSONString(args));
// 执行方法
result = point.proceed();
} catch (Exception e){
}
return result;
}

// 切点表达式的环绕方法
@Around("controllerPoint()&& args(arg)")
public Object controllerMethodAround(ProceedingJoinPoint point,String arg) throws Throwable {
System.out.println(arg);
Signature signature = point.getSignature();
System.out.println(signature.getName());
Object result = point.proceed();

System.out.println(result);
return result;
}
}

1
2
3
4
5
6
7
8
9
@Service
public class CountImpl implements ICount {
// 注解式的实现
@Override
@Action
public int add(int a,int b) {
return a+b;
}
}
1
2
3
4
// 切点表达式的实现
//@Pointcut("execution(* com.stack.config.controller.TaskController.*(..))")
// 符合该(* com.stack.config.controller.TaskController.*(..))条件下的方法都会被做切面处理,当然这个再继续定制化,例如
//根据有无参或者是参数的类型进行是否做切面

切点表达式

1
execution (* com.sample.service.impl..*.*(..))

整个表达式可以分为五个部分:

  • execution(): 表达式主体。

  • 第一个号:表示返回类型,号表示所有的类型。

  • 包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。

  • 第二个号:表示类名,号表示所有的类。

  • *(..):最后这个星号表示方法名,号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。

https://blog.csdn.net/lang_niu/article/details/51559994