Spring AOP 即 Aspect-oriented programming,面向切面编程,是作为面向对象编程的一种补充,专门用于处理系统中分布于各个模块(不同方法)中的交叉关注点的问题。简单地说,就是一个拦截器(interceptor)拦截一些处理过程。
例如,当一个 method 被执行,Spring AOP 能够劫持正在运行的 method,在 method 执行前或者后加入一些额外的功能。
在 Spring AOP 中,支持 4 种类型的通知(Advice):
- Before advice - method 执行前通知。
- After returning advice - method 返回一个结果后通知。
- After throwing advice - method 抛出异常后通知。
- Around advice - 环绕通知,结合了以上三种。
一个 Spring AOP 的实例
下边这个例子解释 Spring AOP 怎样工作。首先一个简单的不使用 AOP 的例子。先创建一个简单的 Service,为了稍后演示,这个类中加了几个简单的打印 method。
创建一个 Maven 项目 SpringAop:
mvn archetype:generate -DgroupId=com.shiyanlou.spring -DartifactId=SpringAop -DarchetypeArtifactId=maven-archetype-quickstart
选择 File->Open Workspace 切换工作空间,选择 SpringAop 目录,必须切换到该目录下,否则识别不了项目,如果没有继承之前的实验环境,请按照实验 2 重新导入 maven 包。
添加 maven 依赖
<?xml version = "1.0" encoding = "UTF-8"?>
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.shiyanlou</groupId>
<artifactId>SpringAop</artifactId>
<version>1.0-SNAPSHOT</version>
<name>SpringAop</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>5.1.1.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.9</version>
</dependency>
</dependencies>
</project>
创建类 CustomerService.java 如下:
package com.shiyanlou.spring.aop.advice;
public class CustomerService {
private String name;
private String url;
public void setName(String name) {
this.name = name;
}
public void setUrl(String url) {
this.url = url;
}
public void printName() {
System.out.println("Customer name : " + this.name);
}
public void printURL() {
System.out.println("Customer website : " + this.url);
}
public void printThrowException() {
throw new IllegalArgumentException();
}
}
在 src/main/resources/ 下新建 xml 配置文件 SpringAOPAdvice.xml 如下:
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id = "customerService" class = "com.shiyanlou.spring.aop.advice.CustomerService">
<property name = "name" value = "Shiyanlou" />
<property name = "url" value = "https://www.lanqiao.cn" />
</bean>
</beans>
将我们项目中的 App.java 移动到 /aop/advice 下,然后在 App.java 中添加如下代码:
package com.shiyanlou.spring.aop.advice;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext appContext = new ClassPathXmlApplicationContext(
new String[] { "SpringAOPAdvice.xml" });
CustomerService cust = (CustomerService) appContext.getBean("customerService");
System.out.println("*************************");
cust.printName();
System.out.println("*************************");
cust.printURL();
System.out.println("*************************");
try {
cust.printThrowException();
} catch (Exception e) {
}
}
}
打开控制器,输入:
mvn compile
mvn exec:java -Dexec.mainClass="com.shiyanlou.spring.aop.advice.App"
实验结果如图: