spring AOP 事务 过滤器(Filter)与拦截器(Interceptor)

目录

AOP

概念

核心术语

实现方式

基于代理的 AOP

基于 AspectJ 的 AOP

示例代码

1. 添加依赖

2. 定义业务接口和实现类

3. 定义切面类

4. 配置 Spring Boot 应用

5. 测试代码

应用场景

AOP 的优缺点

动态切换多数据源

spring事务

基本概念

事务传播行为

事务隔离级别

1. ISOLATION_DEFAULT

2. ISOLATION_READ_UNCOMMITTED

3. ISOLATION_READ_COMMITTED

4. ISOLATION_REPEATABLE_READ

5. ISOLATION_SERIALIZABLE

关键区别总结

实现方式

编程式事务管理

声明式事务管理

应用场景

注意事项

过滤器(Filter)与拦截器(Interceptor)

区别

1. 所属规范和框架

2. 作用范围

3. 实现机制

4. 依赖关系

5. 配置方式

使用场景

过滤器(Filter)的使用场景

拦截器(Interceptor)的使用场景


AOP

Spring AOP(Aspect-Oriented Programming,面向切面编程)是 Spring 框架的一个重要特性,它允许开发者在不修改原有代码的情况下,对程序进行增强。下面从概念、核心术语、实现方式、应用场景等方面进行详细介绍。

概念

在传统的面向对象编程(OOP)中,代码的组织是基于类和对象的,主要关注业务逻辑的实现。然而,有些功能(如日志记录、事务管理、权限验证等)会散布在多个类和方法中,导致代码的重复和耦合度增加。AOP 则是一种新的编程范式,它将这些横切关注点(如日志、事务等)从业务逻辑中分离出来,形成独立的模块(切面),从而提高代码的可维护性和可复用性。

核心术语

  • 切面(Aspect):切面是一个模块化的关注点,它包含了一组通知和切入点。例如,日志记录可以作为一个切面,其中包含了在方法执行前后记录日志的逻辑。
  • 通知(Advice):通知定义了在目标方法执行前后或抛出异常时要执行的代码。常见的通知类型包括:
    • 前置通知(Before Advice):在目标方法执行之前执行。
    • 后置通知(After Advice):在目标方法执行之后执行,无论目标方法是否抛出异常。
    • 返回通知(After Returning Advice):在目标方法正常返回后执行。
    • 异常通知(After Throwing Advice):在目标方法抛出异常后执行。
    • 环绕通知(Around Advice):环绕目标方法的执行,可以在目标方法执行前后进行额外的处理。
  • 切入点(Pointcut):切入点定义了哪些方法会被 AOP 增强。可以使用表达式来指定切入点,例如使用 AspectJ 表达式。例如,execution(* com.example.service.*.*(..)) 表示匹配 com.example.service 包下的所有类的所有方法。
  • 连接点(Join Point):连接点是程序执行过程中的一个点,例如方法调用、异常抛出等。在 Spring AOP 中,连接点通常指的是方法调用。
  • 目标对象(Target Object):目标对象是被 AOP 增强的对象。
  • 代理对象(Proxy Object):代理对象是由 AOP 框架创建的对象,它包含了目标对象的功能,并在目标方法执行前后添加了额外的逻辑。
  • 织入(Weaving):织入是将切面应用到目标对象并创建代理对象的过程。织入可以在编译时、类加载时或运行时进行。

实现方式

Spring AOP 支持两种实现方式:基于代理的 AOP 和基于 AspectJ 的 AOP。

基于代理的 AOP

Spring AOP 默认使用基于代理的 AOP 实现,它又分为 JDK 动态代理和 CGLIB 代理。

  • JDK 动态代理:基于接口的代理,目标对象必须实现至少一个接口。Spring AOP 会创建一个实现了目标对象接口的代理对象,通过反射机制调用目标方法。
  • CGLIB 代理:基于子类的代理,目标对象不需要实现接口。Spring AOP 会创建一个目标对象的子类作为代理对象,通过继承和方法拦截来实现 AOP 增强。
基于 AspectJ 的 AOP

Spring AOP 也支持使用 AspectJ 作为底层实现。AspectJ 是一个功能强大的 AOP 框架,提供了丰富的切面编程语法和工具。Spring AOP 可以与 AspectJ 集成,使用 AspectJ 的注解和语法来定义切面和通知。

示例代码

以下是一个使用 Spring AOP 和 AspectJ 注解实现日志记录的示例:

1. 添加依赖

在 pom.xml 中添加 Spring AOP 和 AspectJ 的依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2. 定义业务接口和实现类
// 业务接口
public interface UserService {
    void addUser(String username);
}

// 业务实现类
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
    @Override
    public void addUser(String username) {
        System.out.println("Adding user: " + username);
    }
}
3. 定义切面类
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {

    // 前置通知
    @Before("execution(* com.example.service.UserService.addUser(..))")
    public void beforeAddUser(JoinPoint joinPoint) {
        System.out.println("Before adding user: " + joinPoint.getArgs()[0]);
    }

    // 后置通知
    @After("execution(* com.example.service.UserService.addUser(..))")
    public void afterAddUser(JoinPoint joinPoint) {
        System.out.println("After adding user: " + joinPoint.getArgs()[0]);
    }
}
4. 配置 Spring Boot 应用

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
5. 测试代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class TestRunner implements CommandLineRunner {

    @Autowired
    private UserService userService;

    @Override
    public void run(String... args) throws Exception {
        userService.addUser("John");
    }
}

应用场景

  • 日志记录:在方法执行前后记录日志,方便调试和监控。
  • 事务管理:在方法执行前后开启和提交事务,确保数据的一致性。
  • 权限验证:在方法执行前进行权限验证,确保用户有权限访问该方法。
  • 性能监控:在方法执行前后记录方法的执行时间,用于性能分析。

综上所述,Spring AOP 是一个强大的工具,可以帮助开发者更好地管理横切关注点,提高代码的可维护性和可复用性。

AOP(Aspect-Oriented Programming)

面向切面编程,用于那些与业务无关,但对多个对象产生影响的公共行为和逻辑,抽取公共模块复用,降低耦合度,提高程序可重用性,提高开发效率。

主要功能:记录操作日志、安全控制、事务处理、异常处理等。

AOP实现:对方法前后进行拦截,在方法执行之前开启事务,在执行完目标方法之后根据执行情况提交或者回滚事务

在方法之前和之后实现处理。在运行期会为目标对象生成一个动态代理对象,并在代理对象中实现对目标对象的增强[用户行为记录、参数的加解密、权限认证、日志记录]

Dynamic  /daɪˈnæmɪk/ 动态的

反射机制通过反射我们可以直接操作类或者对象,比如获取某个对象的类定义,获取类声明的属性和方法,调用方法或者构造对象,甚至可以运行时修改类定义

静态代理:代理类是我们自己定义好的,在程序运行之前就已经编译完成,但是动态代理的代理类是在程序运行时创建的

SpringAOP思想的实现一般都是基于代理模式 ,在Java中采用JDK动态代理模式,但是JDK动态代理模式只能代理接口而不能代理类。因此SpringAOP会在CGLIB、JDK动态代理之间进行切换。

代理类型

代理类型包括:静态代理、动态代理。

动态代理

AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。

JDK动态代理

要求被代理类必须实现一个接口核心是InvocationHandler接口和Proxy类。[ˈprɒksi]

核心其实就是代理对象的生成Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h),通过该方法生成字节码,动态的创建一个代理类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

what_2018

你的鼓励是我前进的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值