Spring - AOP - 介绍

Spring - AOP - 介绍

1. Spring 框架的 AOP

  • Spring 框架的一个关键组件是面向切面的编程(AOP)框架。面向切面的编程需要把程序逻辑分解成不同的部分称为所谓的关注点。跨一个应用程序的多个点的功能被称为横切关注点,这些横切关注点在概念上独立于应用程序的业务逻辑。在软件开发过程中有各种各样的很好的切面的例子,如日志记录、审计、声明式事务、安全性和缓存等。
  • 在 OOP 中,关键单元模块度是类,而在 AOP 中单元模块度是切面。依赖注入帮助你对应用程序对象相互解耦合,AOP 可以帮助你从它们所影响的对象中对横切关注点解耦。AOP 像是编程语言的触发物,如 Perl,.NET,Java 或者其他语言。
  • Spring AOP 模块提供拦截器来拦截一个应用程序,例如,当执行一个方法时,你可以在方法执行之前或之后添加额外的功能。

2. AOP 术语

  • 在我们开始使用 AOP 工作之前,让我们熟悉一下 AOP 概念和术语。这些术语并不特定于 Spring,而是与 AOP 有关的。
描述
Aspect一个模块具有一组提供横切需求的 APIs。例如,一个日志模块为了记录日志将被 AOP 方面调用。应用程序可以拥有任意数量的方面,这取决于需求。
Join point在你的应用程序中它代表一个点,你可以在插件 AOP 方面。你也能说,它是在实际的应用程序中,其中一个操作将使用 Spring AOP 框架。
Advice这是实际行动之前或之后执行的方法。这是在程序执行期间通过 Spring AOP 框架实际被调用的代码。
Pointcut这是一组一个或多个连接点,通知应该被执行。你可以使用表达式或模式指定切入点正如我们将在 AOP 的例子中看到的。
Introduction引用允许你添加新方法或属性到现有的类中。
Target object被一个或者多个方面所通知的对象,这个对象永远是一个被代理对象。也称为被通知对象。
WeavingWeaving 把方面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象。这些可以在编译时,类加载时和运行时完成。

3. 通知的类型

  • Spring 方面可以使用下面提到的五种通知工作:
通知描述
前置通知在一个方法执行之前,执行通知。
后置通知在一个方法执行之后,不考虑其结果,执行通知。
返回后通知在一个方法执行之后,只有在方法成功完成时,才能执行通知。
抛出异常后通知在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知。
环绕通知在建议方法调用之前和之后,执行通知。

4. AOP 入门使用

4.1. pom
    <!-- 依赖项列表,用于指定项目所依赖的外部库 -->
    <dependencies>
        <!-- Spring框架的核心上下文依赖,提供应用程序上下文及相关支持 -->
        <!-- groupId: 组织标识,用于唯一标识项目组织 -->
        <!-- artifactId: 项目标识,用于唯一标识项目中的一个模块 -->
        <!-- version: 版本号,指定所依赖的库的版本 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.1.10</version>
        </dependency>
        <!-- AspectJ依赖,用于实现面向切面编程(AOP)的功能 -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.22.1</version>
        </dependency>
    </dependencies>

4.2. SrpingConfig
/**
 * Spring配置类
 * 该类定义了Spring应用程序的配置方式,包括组件扫描和切面编程的配置。
 */
@Configuration  // 表示该类是一个Spring配置类
@ComponentScan(basePackages = "com.springaop")  // 扫描指定包下的组件
@EnableAspectJAutoProxy // 开启切面编程
public class SpringConfig {
    // 配置类主体为空,通过注解配置应用程序上下文的行为。
}
4.3. UserService
@Service
public class UserService {
    /**
     * 添加用户。
     * 此方法用于模拟用户添加的操作,输出表示用户添加操作的提示信息。
     */
    public void addUser() {
        System.out.println("addUser");
    }

    /**
     * 删除用户。
     * 此方法用于模拟用户删除的操作,输出表示用户删除操作的提示信息。
     */
    public void deleteUser() {
        System.out.println("deleteUser");
    }

    /**
     * 更新用户信息。
     * 此方法用于模拟用户信息更新的操作,输出表示用户信息更新操作的提示信息。
     */
    public void updateUser() {
        System.out.println("updateUser");
    }

    /**
     * 查询用户信息。
     * 此方法用于模拟用户信息查询的操作,输出表示用户信息查询操作的提示信息。
     */
    public void selectUser() {
        System.out.println("selectUser");
    }
}
4.4. UserAspect
/**
 * UserAspect 类用于切面编程,关注 UserService 接口的实现类的方法执行前后的日志记录。
 */
@Component
@Aspect
public class UserAspect {

    /**
     * 声明一个切点表达式,匹配 UserService 接口的所有方法的执行。
     * @param joinPoint 切面连接点,用于获取方法信息和控制方法执行。
     *                  ProceedingJoinPoint 是 JoinPoint 的子接口,允许ProceedingJoinPoint实例调用被拦截方法。
     *                  这里的参数命名为 joinPoint,是按照惯例,表示这是一个连接点。
     *                  方法没有返回值,它的作用是环绕目标方法执行,记录方法执行的时间。
     *                  方法使用 @Around 注解,表示这是一个环绕通知,可以在方法执行前、执行后、甚至根据执行情况决定是否执行目标方法。
     */
    @Around("execution(* com.springaop.service.UserService.*(..))")
    public void log(ProceedingJoinPoint joinPoint) {
        // 记录方法开始执行的时间
        long begin = System.currentTimeMillis();
        try {
            // 执行目标方法
            joinPoint.proceed();
        } catch (Throwable e) {
            // 捕获目标方法执行过程中抛出的任何异常,并记录异常信息
            System.out.println("异常:" + e.getMessage());
        }
        // 记录方法执行结束的时间
        long end = System.currentTimeMillis();
        // 计算并记录方法执行的耗时
        System.out.println("耗时:" + (end - begin) + "ms");
    }
}
4.5. Main
/**
 * 主类,程序的入口点。
 * 使用Spring框架的注解配置方式来初始化应用程序上下文。
 */
public class Main {
    /**
     * 程序入口方法。
     * @param args 命令行参数,本程序中未使用。
     */
    public static void main(String[] args) {
        // 初始化Spring的注解配置上下文
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        // 从上下文中获取UserService的实例
        UserService userService = context.getBean(UserService.class);
        // 调用UserService的addUser方法,演示依赖注入的使用。
        userService.addUser();
    }
}

4.6. 程序输出:
addUser
耗时:0ms
  • 19
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值