前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring AOP的实现原理

Spring AOP的实现原理

原创
作者头像
查拉图斯特拉说
发布2024-02-01 19:56:10
1340
发布2024-02-01 19:56:10
举报
文章被收录于专栏:后端架构后端架构

前言

Spring AOP(面向切面编程)是 Spring 框架中的一个重要功能,它通过在方法调用前后动态地添加额外的功能来实现横切关注点的处理,比如日志记录、性能监控、事务管理等。

Spring AOP

Spring AOP(面向切面编程)是 Spring 框架的一个重要特性,它通过在不修改源代码的情况下,可以将横切逻辑(如日志记录、性能统计、安全控制等)模块化,然后再将这些模块横向地应用到多个对象上。

Spring AOP 动态代理

Spring AOP 的原理基于代理模式和动态代理,它通过在运行时动态地创建代理对象来实现横切逻辑的注入。通常情况下,Spring AOP 通过 JDK 动态代理和 CGLIB 动态代理来实现代理对象的创建,从而实现对目标对象的增强。这样做可以将业务逻辑和横切逻辑分离,提高了代码的模块化和可维护性。

JDK 动态代理

JDK 动态代理适用于基于接口的代理,它要求目标对象实现至少一个接口,代理类通过实现相同的接口来对目标对象进行代理。当目标对象实现接口时,Spring AOP 将会使用 JDK 动态代理来创建代理对象。

CGLIB 动态代理

CGLIB 动态代理则适用于没有实现接口的类。当目标对象没有实现接口时,Spring AOP 将会使用 CGLIB 动态代理来创建代理对象。

小结

因此,Spring AOP 可以根据目标对象是否实现接口来灵活地选择使用 JDK 动态代理或 CGLIB 动态代理,以实现对目标对象的增强。

日常的使用场景

比如,假设我们有一个应用程序,其中有多个服务类负责处理不同的业务逻辑,我们希望在每个服务类的方法执行前后记录日志。

通过使用 Spring AOP,我们可以创建一个切面(Aspect),在切面中定义一个通知(Advice),在通知中编写日志记录的逻辑。然后,我们可以将这个切面应用到所有的服务类上,而不需要修改服务类的源代码。

当调用服务类的方法时,Spring AOP 会动态地创建代理对象,并在方法执行前后执行切面中定义的日志记录逻辑,从而实现了横切逻辑的模块化和复用。

代码示例

首先,我们创建一个简单的 Spring Boot 应用程序,包括一个 UserService 接口和它的实现类 UserServiceImpl

代码语言:javascript
复制
public interface UserService {
    void createUser(String username);
}

@Service
public class UserServiceImpl implements UserService {
    @Override
    public void createUser(String username) {
        System.out.println("Creating user: " + username);
    }
}

接着,我们创建一个切面类 LoggingAspect,定义一个前置通知和一个后置通知:

代码语言:javascript
复制
@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* com.example.UserService.createUser(String)) && args(username)")
    public void logBefore(JoinPoint joinPoint, String username) {
        System.out.println("Before creating user: " + username);
    }

    @After("execution(* com.example.UserService.createUser(String)) && args(username)")
    public void logAfter(JoinPoint joinPoint, String username) {
        System.out.println("After creating user: " + username);
    }
}

最后,在应用程序的入口类上添加 @EnableAspectJAutoProxy 注解来启用 Spring AOP:

代码语言:javascript
复制
@SpringBootApplication
@EnableAspectJAutoProxy
public class MyApplication {

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

这样,当调用 createUser 方法时,Spring AOP 将会在方法执行前后执行切面中定义的日志记录逻辑。

Spring AOP底层源码解析

Spring AOP 主要基于代理模式和动态代理实现。它通过 JDK 动态代理和 CGLIB 动态代理来创建代理对象,从而实现对目标对象的增强。当目标对象实现接口时,Spring AOP 会使用 JDK 动态代理;当目标对象没有实现接口时,Spring AOP 会使用 CGLIB 动态代理。

在 Spring AOP 中,核心的类包括 `ProxyFactory`、`AopProxy`、`AdvisedSupport` 等。

  • `ProxyFactory` 是用于创建代理对象的工厂类
  • `AopProxy` 是代理对象的接口,它定义了获取代理对象的方法
  • `AdvisedSupport` 则包含了切面、目标对象等信息

org.springframework.aop.framework.DefaultAopProxyFactory这是处理的主要类,用来区分使用不同的代理类,是接口还是类,针对不同的类进行不同的代理操作,以达到环切的目的。

ProxyFactory包装了ProxyCreatorSupport类,对其进行封装管理代理对象,而ProxyCreatorSupport提供默认动态代理实现类的创建。

通过org.springframework.aop.framework.ProxyCreatorSupport#createAopProxy类进行默认代理类的创建。

通过org.springframework.aop.aspectj.annotation.AspectJProxyFactory类,您可以方便地创建代理对象,并将AspectJ的切面应用到目标对象上。它提供了一种简单的方式来使用AspectJ的切面功能,而不需要显式地配置AOP代理。Spring AOP 主要通过以下步骤:定义切面,创建代理对象,执行通知。

总结

总的来说,Spring AOP能够使编码更好地管理横切关注点,降低系统的复杂度,提高代码的可维护性和可重用性。

最后 点赞关注评论一键三连,每周分享技术干货、开源项目、实战经验、国外优质文章翻译等,您的关注将是我的更新动力

我正在参与2024腾讯技术创作特训营第五期有奖征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • Spring AOP
    • Spring AOP 动态代理
      • JDK 动态代理
      • CGLIB 动态代理
      • 小结
    • 日常的使用场景
    • 代码示例
    • Spring AOP底层源码解析
    • 总结
    相关产品与服务
    应用性能监控
    应用性能监控(Application Performance Management,APM)是一款应用性能管理平台,基于实时多语言应用探针全量采集技术,为您提供分布式性能分析和故障自检能力。APM 协助您在复杂的业务系统里快速定位性能问题,降低 MTTR(平均故障恢复时间),实时了解并追踪应用性能,提升用户体验。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档