原文: https://javatutorial.net/core-concepts-and-advice-types-in-aop-in-spring
如果您熟悉 Spring,可能已经听说过面向方面的编程(AOP)。 那是 Spring 框架的主要组成部分之一。
但是,不需要以前的 AOP 经验。 它面向希望了解 Spring 中 AOP 框架如何工作的完整初学者。
在面向对象的编程中,可以通过使用类实现应用程序的模块化。 在面向方面的编程中,它是通过切片实现的。 这些方面允许分离切片 。换句话说,它可以向现有代码添加功能,而无需实际对其进行修改。 此外,我们可以分别声明新功能和这些新行为。
AOP 中的核心概念
AOP 中有 7 个核心概念。
- 业务对象:正常的业务逻辑。
- 方面:实现跨多个类的企业应用程序关注点。
- 连接点:应用程序中的特定点,例如变量值,异常处理,方法执行等。
- 建议:针对特定连接点采取的操作。
- 切入点:与连接点匹配的表达式,其目的是确定是否需要执行建议。
- 目标对象:建议适用于此。
- AOP 代理:使用 JDK 动态代理创建的 AOP 实现类,以使用目标类和建议调用/调用创建代理类。
- 编织:将方面与其他对象链接在一起的过程,目的是创建建议的代理对象。
有关这些概念的更多信息,请单击此处。
要实现Business
对象类,请看下面的示例:
public class Example {
public String printHelloWorld() {
return "Hello World!";
}
public String printMessage(String msg) {
return msg;
}
}
这是完全普通的类,没有任何与 Spring 相关的注释。
AOP 建议类型
- 在建议之前:这些建议在执行连接点方法之前运行。 要将建议类型标记为之前,我们可以使用
@Before
注释。 - 建议之后:这些建议在执行连接点方法之后运行。 要将建议类型标记为
After
,可以使用@After
注解。 - 返回建议之后:仅在连接点方法正常执行(不表示异常)时运行这些建议。 要将建议类型标记为“返回后”,我们可以使用
@AfterReturning
注解。 - 抛出建议后:仅在连接点方法抛出异常时才运行这些建议(与“返回建议之后”相反)。 要将建议类型标记为“抛后”,我们可以使用
@AfterThrowing
注解。 - 围绕建议:这些建议为我们提供了灵活性,因为借助它们的使用,我们可以选择是否执行连接点方法。
让我们看看如何实现这些不同的建议类型。
建议之前
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
。
建议后
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
}
}
与“建议之前”实现非常相似,只有我们将“之前”替换为“之后”。
返回建议后
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
}
}
你看到模式了吗?
提出建议后
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()
。
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;
}
}