Spring(三):注解式AOP的使用
Spring 支持 AspectJ的注解式切面编程。AOP可以让一组类共享相同的行为。
注解
- 使用
@Aspect
声明一个切面。 - 使用
@After,@Before,@Around
定义建言(Advice
),可以直接拦截规则(切点)作为参数。 - 其中**@After,@Before,@Around参数的拦截规则为切点(PointCut),为了使切点复用,可使用
@PointCut
专门定义拦截规则,然后在@After,@Before,@Around**的参数中调用。 - 其中符合条件的每一个被拦截处为连接点(
JoinPoint
)。
示例
- 编写拦截规则的注解
1
2
3
4
5
6
7
8
9
10
11
12
13
14package com.aop;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public Action {
String name();
} - 编写使用注解的被拦截的类
1
2
3
4
5
6
7
8
9
10
11
12package com.aop;
import org.springframework.stereotype.Service;
public class DemoAnnotationService {
public void add() {
System.out.println("DemoAnnotationService ---");
}
} - 编写使用方法规则的被拦截的类
1
2
3
4
5
6
7
8
9
10
11
12package com.aop;
import org.springframework.stereotype.Service;
public class DemoMethodService {
public void add() {
System.out.println("DemoMethodService ---");
}
} - 编写切点
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
35package com.aop;
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
//声明一个切面
//成为spring容器中的一个Bean
public class LogAspect {
//声明切点
public void annotationPointCut() {};
//声明建言,并使用@Pointcut定义切点
public void after(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Action action = method.getAnnotation(Action.class);
System.out.println("注解式拦截,在方法执行之后拦截: " + action.name());//通过反射获取注解上的属性
}
public void before(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
System.out.println("方法规则式拦截,方法执行之前拦截:" + method.getName());
}
} - 编写配置类
1
2
3
4
5
6
7
8
9
10
11
12
13package com.aop;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
//开启spring对AspectJ的支持
public class AopConfig {
} - 运行测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18package com.aop;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class AopMain {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class);
DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);
DemoMethodService demoMethodService = context.getBean(DemoMethodService.class);
demoAnnotationService.add();
demoMethodService.add();
context.close();
}
} - 运行结果
1
2
3
4DemoAnnotationService ---
注解式拦截,在方法执行之后拦截: 注解释拦截的add操作
方法规则式拦截,方法执行之前拦截:add
DemoMethodService ---
Spring(三):注解式AOP的使用
http://blog.gxitsky.com/2018/02/27/Spring-03-aop-annotation/