📜  Spring AOP-核心概念(1)

📅  最后修改于: 2023-12-03 15:20:12.415000             🧑  作者: Mango

Spring AOP - 核心概念

什么是AOP?

AOP(Aspect Oriented Programming),面向切面编程,是一种在 OOP(Object Oriented Programming)之外的编程思想。它将业务逻辑中的横向关注点(比如日志、安全、事务等)和纵向关注点(业务逻辑)分离开来,使得系统更加解耦、易于维护。

Spring AOP简介

Spring AOP(AspectJ-oriented)是 Spring 框架的一个重要组成部分,主要基于 AOP Alliance 规范和 AspectJ 语法实现。它提供了一种将横向关注点封装成切面,并将这些切面嵌入到被应用程序中的业务逻辑中的方法。Spring AOP 的实现是基于代理机制,即通过代理对象实现切面,来达到对目标对象进行增强(即添加横向切面逻辑)的目的。

Spring AOP的核心概念
切面

切面(Aspect)是将横向关注点封装成的类,在 Spring AOP 中,它是一个普通的 JavaBean,通常定义为一个切面类(Aspect Class)。切面类是可重用的代码单元,它提供了一组横向关注点,可以被不同的切点(Join Point)引入。切面类通常包含了一些列的通知(Advice)和切点的定义,用于描述在哪些方法、类、包等位置应用哪些通知。

通知

通知(Advice)是定义在切面中的方法,用于描述在切点执行时应该执行的业务逻辑。Spring AOP 提供了五种不同类型的通知:

  • 前置通知(Before Advice):在方法执行之前执行;
  • 后置通知(After Advice):在方法执行之后执行;
  • 返回通知(After Returning Advice):在方法返回结果时执行;
  • 异常通知(After Throwing Advice):在方法抛出异常时执行;
  • 环绕通知(Around Advice):在方法执行前后都执行。
切点

切点(Join Point)是应用程序执行过程中的特定点,比如类中的方法执行、方法中的语句执行、对象创建、属性修改等。在 Spring AOP 中,切点表示一个或多个与通知相关联的连接点,它通过通知来织入切面中的业务逻辑。Spring AOP 使用 AspectJ 语言提供了一套切点表达式,它可以用来匹配切点所在的方法、类、参数类型等。

切面中的织入

织入(Weaving)是将切面应用到目标对象中的过程,在 Spring AOP 中,织入是通过代理机制实现的。当创建目标对象时,Spring AOP 自动创建代理对象,并将需要增强的通知织入到代理对象中。代理对象负责将被增强的方法调用委托给目标对象,并在调用前后执行通知,从而实现切面的功能。

示例

下面是一个简单的例子,使用 Spring AOP 实现一个简单的日志切面:

@Aspect
@Component
public class LogAspect {
    
    @Pointcut("execution(* com.example.demo.service.*.*(..))")
    private void serviceLayer() {}

    @Before("serviceLayer()")
    public void before(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("调用方法:" + methodName + ",参数:" + Arrays.toString(args));
    }

    @AfterReturning(value = "serviceLayer()", returning = "returnValue")
    public void afterReturn(JoinPoint joinPoint, Object returnValue) {
        String methodName = joinPoint.getSignature().getName();
        System.out.println("调用方法:" + methodName + ",返回值:" + returnValue);
    }

}

在上面的代码中,我们定义了一个切面类 LogAspect,包含了两个通知,BeforeAfterReturning。在 Before 通知中,我们打印了目标方法的名称和参数;在 AfterReturning 通知中,我们打印了目标方法的名称和返回值。通过 @Pointcut 注解,我们定义了一个切点,代表所有在包 com.example.demo.service 中的方法调用。最后,在主程序中,我们使用 @EnableAspectJAutoProxy 注解开启自动代理,在运行时 Spring AOP 会自动创建切面类 LogAspect 的代理对象。

@EnableAspectJAutoProxy
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

以上代码展示了 Spring AOP 的核心概念,更多细节请参考 Spring AOP 官方文档。