原文: https://javatutorial.net/core-concepts-and-advice-types-in-aop-in-spring

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

Spring AOP 中的核心概念和建议类型 - 图1

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

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

AOP 中的核心概念

AOP 中有 7 个核心概念。

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

有关这些概念的更多信息,请单击此处

要实现Business对象类,请看下面的示例:

  1. public class Example {
  2. public String printHelloWorld() {
  3. return "Hello World!";
  4. }
  5. public String printMessage(String msg) {
  6. return msg;
  7. }
  8. }

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

AOP 建议类型

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

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

建议之前

  1. import org.aspectj.lang.annotation.Aspect;
  2. import org.aspectj.lang.annotation.Before;
  3. @Aspect
  4. public class BeforeAdviceDemo {
  5. @Before("com.xyz.demoapp.SystemArchitecture.dataAccessOperation()")
  6. public void methodName() {
  7. // write code here
  8. }
  9. }

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

建议后

  1. import org.aspectj.lang.annotation.Aspect;
  2. import org.aspectj.lang.annotation.Before;
  3. @Aspect
  4. public class AfterAdviceDemo{
  5. @After("com.xyz.demoapp.SystemArchitecture.dataAccessOperation()")
  6. public void methodName() {
  7. // write code here
  8. }
  9. }

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

返回建议后

  1. import org.aspectj.lang.annotation.Aspect;
  2. import org.aspectj.lang.annotation.Before;
  3. @Aspect
  4. public class AfterReturningAdviceDemo{
  5. @AfterReturning("com.xyz.demoapp.SystemArchitecture.dataAccessOperation()")
  6. public void methodName() {
  7. // write code here
  8. }
  9. }

你看到模式了吗?

提出建议后

  1. import org.aspectj.lang.annotation.Aspect;
  2. import org.aspectj.lang.annotation.Before;
  3. @Aspect
  4. public class AfterThrowingAdviceDemo {
  5. @AfterThrowing("com.xyz.demoapp.SystemArchitecture.dataAccessOperation()")
  6. public void methodName() {
  7. // write code here
  8. }
  9. }

建议

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

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

  1. import org.aspectj.lang.annotation.Aspect;
  2. import org.aspectj.lang.annotation.Around;
  3. import org.aspectj.lang.ProceedingJoinPoint;
  4. @Aspect
  5. public class AroundAdviceDemo {
  6. @Around("com.xyz.demoapp.SystemArchitecture.businessService()")
  7. public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
  8. Object value = pjp.proceed();
  9. // return the object
  10. return value;
  11. }
  12. }