# Spring AOP 中的核心概念和建议类型

> 原文： [https://javatutorial.net/core-concepts-and-advice-types-in-aop-in-spring](https://javatutorial.net/core-concepts-and-advice-types-in-aop-in-spring)

如果您熟悉 Spring，可能已经听说过面向方面的编程（AOP）。 那是 Spring 框架的主要组成部分之一。

![spring-featured-image](img/d2f73752d8ae931b119dec1eac866973.jpg)

但是，不需要以前的 AOP 经验。 它面向希望了解 Spring 中 AOP 框架如何工作的完整初学者。

在面向对象的编程中，可以通过使用**类**实现应用程序的模块化。 在面向方面的编程中，它是通过**切片**实现的。 这些方面允许分离**切片** 。换句话说，它可以向现有代码添加功能，而无需实际对其进行修改。 此外，我们可以分别声明新功能和这些新行为。

## AOP 中的核心概念

AOP 中有 7 个核心概念。

1.  业务对象：正常的业务逻辑。
2.  方面：实现跨多个类的企业应用程序关注点。
3.  连接点：应用程序中的特定点，例如变量值，异常处理，方法执行等。
4.  建议：针对特定连接点采取的操作。
5.  切入点：与连接点匹配的表达式，其目的是确定是否需要执行建议。
6.  目标对象：建议适用于此。
7.  AOP 代理：使用 [JDK](https://javatutorial.net/install-java-8-jdk-on-ubuntu) 动态代理创建的 AOP 实现类，以使用目标类和建议调用/调用创建代理类。
8.  编织：将方面与其他对象链接在一起的过程，目的是创建建议的代理对象。

有关这些概念的更多信息，[请单击此处](https://www.journaldev.com/2583/spring-aop-example-tutorial-aspect-advice-pointcut-joinpoint-annotations)。

要实现`Business`对象类，请看下面的示例：

```java
public class Example {

    public String printHelloWorld() {
        return "Hello World!";
    }

    public String printMessage(String msg) {
        return msg;
    }

}
```

这是完全普通的类，没有任何与 Spring 相关的注释。

### AOP 建议类型

1.  在建议之前：这些建议在执行连接点方法之前运行。 要将建议类型标记为之前，我们可以使用`@Before`注释。
2.  建议之后：这些建议在执行连接点方法之后运行。 要将建议类型标记为`After`，可以使用`@After`注解。
3.  返回建议之后：仅在连接点方法正常执行（不表示异常）时运行这些建议。 要将建议类型标记为“返回后”，我们可以使用`@AfterReturning`注解。
4.  抛出建议后：仅在连接点方法抛出异常时才运行这些建议（与“返回建议之后”相反）。 要将建议类型标记为“抛后”，我们可以使用`@AfterThrowing`注解。
5.  围绕建议：这些建议为我们提供了灵活性，因为借助它们的使用，我们可以选择是否执行连接点方法。

让我们看看如何实现这些不同的建议类型。

**建议之前**

```java
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class BeforeAdviceDemo {
	@Before("com.xyz.demoapp.SystemArchitecture.dataAccessOperation()")
	public void methodName() {
		// write code here
	}
}
```

通过使用`@Before`注解，我们指定这是一个`BeforeAdvice`。

**建议后**

```java
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class AfterAdviceDemo{
	@After("com.xyz.demoapp.SystemArchitecture.dataAccessOperation()")
	public void methodName() {
		// write code here
	}
}
```

与“建议之前”实现非常相似，只有我们将“之前”替换为“之后”。

**返回建议后**

```java
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class AfterReturningAdviceDemo{
	@AfterReturning("com.xyz.demoapp.SystemArchitecture.dataAccessOperation()")
	public void methodName() {
		// write code here
	}
}
```

你看到模式了吗？

**提出建议后**

```java
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class AfterThrowingAdviceDemo {
	@AfterThrowing("com.xyz.demoapp.SystemArchitecture.dataAccessOperation()")
	public void methodName() {
		// write code here
	}
}
```

**建议**

`Around`类型的实现有些棘手。 由于这种类型的建议可以在方法执行之前和之后执行工作，因此它需要以线程安全的方式共享该方法执行之前和之后的状态。

要指定建议类型，我们使用`@Around`注释，该建议方法的第一个参数必须为`ProceedingJoinPoint`类型。 要执行基础方法，我们需要调用`proced()`。

```java
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;

@Aspect
public class AroundAdviceDemo {

  @Around("com.xyz.demoapp.SystemArchitecture.businessService()")
  public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
    Object value = pjp.proceed();
	// return the object
    return value;
  }

}
```