spring aop 常用的有以下:

  • 通知类型:
  • 前置通知(Before advice):在某连接点之前执行的通知,但这个通知不能阻止连接点之前的执行流程(除非它抛出一个异常)。
  • 后置通知(After returning advice):在某连接点正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
  • 异常通知(After throwing advice):在方法抛出异常退出时执行的通知。
  • 最终通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
  • 环绕通知(Around Advice):包围一个连接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它自己的返回值或抛出异常来结束执行。
  • 核心配置只要在 AOP 的实现方法上加上@Aspect 与在 spring 配置文件中加上 aop:aspectj-autoproxy/,spring 就可以配置 aop 方法,然后再根据方法的增强标签不同的效果,这里需要注意是它们的参数不同。
  • pom.xml
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>mrwood_study</artifactId>
<groupId>xyz.mrwood.study</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>study-spring-aop</artifactId>
<packaging>jar</packaging>

<name>study-spring-aop</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.2.5.RELEASE</spring.version>

</properties>

<dependencies>
<!-- spring开始 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring 结束-->

<!-- AOP begin -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- AOP end -->

<!-- 日志开始 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<!-- 日志结束 -->

</dependencies>
</project>
  • spring-context.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
<?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="xyz.mrwood.study"/>

<!--开启aop-->
<aop:aspectj-autoproxy/>
</beans>
  • AopHandler.java
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
* Copyright (c) 2016, 791650277@qq.com(Mr.kiwi) All Rights Reserved.
*/
package xyz.mrwood.study.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
* 项目:study
* 包名:xyz.mrwood.study.aop
* 功能:aop实现
* 时间:2016-05-28 10:33
* 作者:Mr.Kiwi
* 通知类型:
* 前置通知(Before advice):在某连接点之前执行的通知,但这个通知不能阻止连接点之前的执行流程(除非它抛出一个异常)。
* 后置通知(After returning advice):在某连接点正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
* 异常通知(After throwing advice):在方法抛出异常退出时执行的通知。
* 最终通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
* 环绕通知(Around Advice):包围一个连接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它自己的返回值或抛出异常来结束执行。
*/
@Aspect
@Component
public class AopHandler {

/**
* 拦截工程下所有的切点
*/
@Pointcut("execution(* xyz.mrwood.study..*.*(..))")
public void getAllPoint() {
}

/**
* 拦截所有service层下的切点
*/
@Pointcut("execution(* xyz.mrwood.study.service..*.*(..))")
public void getServicePoint() {
}


/**
* 前置增强
* @param joinPoint
*/
@Before("getServicePoint()")
public void beforeMethod(JoinPoint joinPoint){

System.out.println("[前置增强开始]:" + "方法开始了");
}

@AfterThrowing(value = "getServicePoint()", throwing = "ex")
public void exceptionMethod(JoinPoint joinPoint, Exception ex){

System.out.println("[异常增强]:" + "如果你看到这行,就说明你的程序报错了!" + "异常信息:" + ex.getMessage());
}

/**
* 后置增强,只有在方法正常结束才会调用
* @param returnVal
*/
@AfterReturning(value = "getServicePoint()",returning = "returnVal")
public void afterReturningMethod(Object returnVal){

System.out.println("[后置增强]:" + "当你看到这个说明,你的方法没有正常结束了!" + "它的返回值为:" + returnVal);
}

/**
* 最终增强,类似于finally的功能
*/
@After("getServicePoint()")
public void afterMethod(){

System.out.println("[最终增强]:" + "无论发论发生什么事,我都会运行!");
}

/**
* 环绕增强
* @param proceedingJoinPoint
*/
@Around("getServicePoint()")
public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

System.out.println("[环绕增强开始]:" + "方法开始了!");
Object returnVal = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
System.out.println("[环绕增强结束]:" + "方法已经结束了!");

return returnVal;
}
}
  • TargetService.java
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
/**
* Copyright (c) 2016, 791650277@qq.com(Mr.kiwi) All Rights Reserved.
*/
package xyz.mrwood.study.service;

import org.springframework.stereotype.Component;

/**
* 项目:study
* 包名:xyz.mrwood.study.service
* 功能:被拦截的目标类
* 时间:2016-05-28 10:32
* 作者:Mr.Kiwi
*/
@Component
public class TargetService {

public String hello(String name){

return "hello " + name;
}

public String test(){


return "test";
}
}
  • 运行结果
1
2
3
4
5
[环绕增强开始]:方法开始了!
[前置增强开始]:方法开始了
[环绕增强结束]:方法已经结束了!
[最终增强]:无论发论发生什么事,我都会运行!
[后置增强]:当你看到这个说明,你的方法没有正常结束了!它的返回值为:test

本文地址 https://blog.coder4j.cn/posts/e66e4043/