Spring Framework 源码学习笔记(七)- AOP(下)

简介: Spring Framework 源码学习笔记(七)- AOP

上述源码总结起来其实就是通过@EnableAspectProxy中的AspectAutoProxyRegistrar给容器中注入了一个AnnotationAwareAspectJAutoProxyCreator,这个类的作用就是创建Aspect切面代理,这也就是整个AOP的原理,查看AnnotationAwareAspectJAutoProxyCreator继承关系图

65d3d05708624ce9b1d32fa5d65a21c2_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

该类间接实现类BeanFactoryAware接口,也就拥有了beanFactory的功能,实现了BeanPostProcessor,也就实现了前置后置处理器的功能

AnnotationAwareAspectJAutoProxyCreator创建注册流程

在test包中新建一个测试类BeanConfigTest

@SpringBootTest
public class BeanConfigTest {
    @Test
    public void getBean(){
        ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
        String[] beanNames = context.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            System.out.println(beanName);
        }
    }
}
复制代码

在new AnnotationConfigApplicationContext(BeanConfig.class)这一行打断点,启动Debug模式

1.register()传入配置类BeanConfig,准备开始创建容器

cbbcb8b2fbc5438786530bdcc4cb661e_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

2.refresh()刷新容器,进入refresh()方法

3.registerBeanPostProcessors(),注册Bean的后置处理器拦截,处理流程为

1)获取IoC容器中所有的postProcessors

String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
复制代码

2)给容器中增加BeanPostProcessor

beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
复制代码

3)先注册实现了PriorityOrdered接口的BeanPostProcessor 再注册实现类Ordered接口的,最后注册没有实现Ordered接口的

for (String ppName : postProcessorNames) {
   if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      priorityOrderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
      orderedPostProcessorNames.add(ppName);
   }
   else {
      nonOrderedPostProcessorNames.add(ppName);
   }
}
复制代码

e9d644d6f80347b196c654bbbc773b29_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

Bean Name为org.springframework.aop.config.internalAutoProxyCreator其实就是 AnnotationAwareAspectJAutoProxyCreator

4)再进入getBean()

bc0572afe597453b8457e86acabb59b2_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

  1. 接下来就是创建Bean的流程了,与创建普通的业务Bean流程一致

0d49c8af19014772ba399f56011a89fc_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

6) Bean创建完成之后会执行

beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
复制代码

将Bean注册到容器中

创建增强型业务Bean HelloController流程

在PostProcessor后置处理器创建成功之后,才会创建业务Bean, refresh() --> finishBeanFactoryInitilization()完成BeanFactory的初始化工作,然后开始创建Bean

创建业务Bean流程中的createBean()方法这里返回一个增强代理Bean,创建一个代理对象

7365870d389b44a4b56c0649a26a2d53_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

进入resolveBeforeInstantiation,这里判断是否实现InstantiationAwareBeanPostProcessors

16e5c137a71943ce88c2eb72e60b5aab_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

0e5d164fcda045ffa07a357046cff5c7_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

进入 postProcessBeforeInstantiation,开始创建代理对象

35cdca2093c845088329d5453a979dc9_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

createProxy() --> proxyFactory.getProxy(getProxyClassLoader()) --> createAopProxy

AOP两种实现方式

d621227cdf6f47a1badd8e814c14deef_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

接着就是执行doCreateBean() ...., 和创建单实例Bean的流程一致

InstantiationAwareBeanPostProcessor

每一个Bean创建之前都会调用postProcessBeforeInstantiation(),这个方法会判断当前Bean是否存在advisedBeans中,adivsedBeans中保存了所有需要增强的Bean,这里就跟AOP类LogAspect有关

LogAspect执行的方法

181f30083df64656943772961152c08f_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

3a08e2912d874306ba78ba328e1843b4_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

总结

  1. @EnableAspectJAutoProxy 开启AOP功能
  2. @EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator
  3. AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;
  4. 容器的创建流程:
    4-1. registerBeanPostProcessors()注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator对象
    4-2. finishBeanFactoryInitialization() 初始化剩下的单实例bean
    4-2-1. 创建业务逻辑组件和切面组件 AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
    4-2-2. 组件创建完之后,判断组件是否需要增强 是:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(cglib);
  5. 执行目标方法:
    5-1. 代理对象执行目标方法
    5-2. CglibAopProxy.intercept();
    5-2-1. 得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
    5-2-2. 利用拦截器的链式机制,依次进入每一个拦截器进行执行;
    5-2-3. 效果:

正常执行:前置通知-》目标方法-》后置通知-》返回通知

出现异常:前置通知-》目标方法-》后置通知-》异常通知


相关文章
|
5天前
|
搜索推荐 JavaScript Java
基于springboot的儿童家长教育能力提升学习系统
本系统聚焦儿童家长教育能力提升,针对家庭教育中理念混乱、时间不足、个性化服务缺失等问题,构建科学、系统、个性化的在线学习平台。融合Spring Boot、Vue等先进技术,整合优质教育资源,提供高效便捷的学习路径,助力家长掌握科学育儿方法,促进儿童全面健康发展,推动家庭和谐与社会进步。
|
1月前
|
XML 安全 Java
使用 Spring 的 @Aspect 和 @Pointcut 注解简化面向方面的编程 (AOP)
面向方面编程(AOP)通过分离横切关注点,如日志、安全和事务,提升代码模块化与可维护性。Spring 提供了对 AOP 的强大支持,核心注解 `@Aspect` 和 `@Pointcut` 使得定义切面与切入点变得简洁直观。`@Aspect` 标记切面类,集中处理通用逻辑;`@Pointcut` 则通过表达式定义通知的应用位置,提高代码可读性与复用性。二者结合,使开发者能清晰划分业务逻辑与辅助功能,简化维护并提升系统灵活性。Spring AOP 借助代理机制实现运行时织入,与 Spring 容器无缝集成,支持依赖注入与声明式配置,是构建清晰、高内聚应用的理想选择。
304 0
|
5月前
|
监控 安全 Java
Spring AOP实现原理
本内容主要介绍了Spring AOP的核心概念、实现机制及代理生成流程。涵盖切面(Aspect)、连接点(Join Point)、通知(Advice)、切点(Pointcut)等关键概念,解析了JDK动态代理与CGLIB代理的原理及对比,并深入探讨了通知执行链路和责任链模式的应用。同时,详细分析了AspectJ注解驱动的AOP解析过程,包括切面识别、切点表达式匹配及通知适配为Advice的机制,帮助理解Spring AOP的工作原理与实现细节。
|
2月前
|
人工智能 监控 安全
Spring AOP切面编程颠覆传统!3大核心注解+5种通知类型,让业务代码纯净如初
本文介绍了AOP(面向切面编程)的基本概念、优势及其在Spring Boot中的使用。AOP作为OOP的补充,通过将横切关注点(如日志、安全、事务等)与业务逻辑分离,实现代码解耦,提升模块化程度、可维护性和灵活性。文章详细讲解了Spring AOP的核心概念,包括切面、切点、通知等,并提供了在Spring Boot中实现AOP的具体步骤和代码示例。此外,还列举了AOP在日志记录、性能监控、事务管理和安全控制等场景中的实际应用。通过本文,开发者可以快速掌握AOP编程思想及其实践技巧。
|
2月前
|
人工智能 监控 安全
如何快速上手【Spring AOP】?核心应用实战(上篇)
哈喽大家好吖~欢迎来到Spring AOP系列教程的上篇 - 应用篇。在本篇,我们将专注于Spring AOP的实际应用,通过具体的代码示例和场景分析,帮助大家掌握AOP的使用方法和技巧。而在后续的下篇中,我们将深入探讨Spring AOP的实现原理和底层机制。 AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的核心特性之一,它能够帮助我们解决横切关注点(如日志记录、性能统计、安全控制、事务管理等)的问题,提高代码的模块化程度和复用性。
|
7月前
|
监控 Java 应用服务中间件
微服务——SpringBoot使用归纳——为什么学习Spring Boot
本文主要探讨为什么学习Spring Boot。从Spring官方定位来看,Spring Boot旨在快速启动和运行项目,简化配置与编码。其优点包括:1) 良好的基因,继承了Spring框架的优点;2) 简化编码,通过starter依赖减少手动配置;3) 简化配置,采用Java Config方式替代繁琐的XML配置;4) 简化部署,内嵌Tomcat支持一键式启动;5) 简化监控,提供运行期性能参数获取功能。此外,从未来发展趋势看,微服务架构逐渐成为主流,而Spring Boot作为官方推荐技术,与Spring Cloud配合使用,将成为未来发展的重要方向。
221 0
微服务——SpringBoot使用归纳——为什么学习Spring Boot
|
2月前
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
|
4月前
|
安全 Java 数据库
Spring Boot 框架深入学习示例教程详解
本教程深入讲解Spring Boot框架,先介绍其基础概念与优势,如自动配置、独立运行等。通过搭建项目、配置数据库等步骤展示技术方案,并结合RESTful API开发实例帮助学习。内容涵盖环境搭建、核心组件应用(Spring MVC、Spring Data JPA、Spring Security)及示例项目——在线书店系统,助你掌握Spring Boot开发全流程。代码资源可从[链接](https://pan.quark.cn/s/14fcf913bae6)获取。
516 2
|
6月前
|
Java Spring
Spring框架的学习与应用
总的来说,Spring框架是Java开发中的一把强大的工具。通过理解其核心概念,通过实践来学习和掌握,你可以充分利用Spring框架的强大功能,提高你的开发效率和代码质量。
153 20
|
8月前
|
XML Java 测试技术
Spring AOP—通知类型 和 切入点表达式 万字详解(通俗易懂)
Spring 第五节 AOP——切入点表达式 万字详解!
400 25