学习编程|Spring源码深度解析 读书笔记 第4章:bean的加载
在Spring框架中,bean的源码源码加载过程是一个精细且有序的过程。首先,分析当需要加载bean时,水平Spring会尝试通过转换beanName来识别目标对象,均衡可能涉及到别名或FactoryBean的源码源码招标投标系统源码识别。
加载过程分为几步:从缓存查找单例,分析Spring容器内单例只创建一次,水平若缓存中无数据,均衡会尝试从singletonFactories寻找。源码源码接着是分析bean的实例化,从缓存获取原始状态后,水平可能需要进一步处理以符合预期状态。均衡
原型模式的源码源码依赖检查是单例模式特有的,用来避免循环依赖问题。分析然后,如果缓存中无数据,会检查parentBeanFactory,递归加载配置。BeanDefinition会被转换为RootBeanDefinition,合并父类属性,确保依赖的正确初始化。
Spring根据不同的scope策略创建bean,如singleton、prototype等。类型转换是后续步骤,可能将返回的bean转换为所需的类型。FactoryBean的源码笔记33使用提供了灵活的实例化逻辑,用户自定义创建bean的过程。
当bean为FactoryBean时,getBean()方法代理了FactoryBean的getObject(),允许通过不同的方式配置bean。缓存中获取单例时,会执行循环依赖检测和性能优化。最后,通过ObjectFactory实例singletonFactory定义bean的完整加载逻辑,包括回调方法用于处理单例创建前后的状态。
Spring Configuration:@Import的用法和源码解析
Spring 3.0之后的@Configuration注解和注解配置体系革新了bean的配置方式。本文主要解析@Import的用法和源码实现。1. @Import的用法
配置类,如带有@Configuration注解的类,可作为bean注册起点。除了@Bean方法声明bean,@Import注解允许批量注册相关bean。例如,WebMvcConfig通过@Import导入其他配置类,同时借助@EnableWebMvc导入另一配置类。2. 直接导入
用户可以通过@Import注解在配置类上导入一个或多个类,甚至可以嵌套在父类注解中,如WebMvcConfig导入的DelegatingWebMvcConfiguration。3. ImportBeanDefinitionRegistrar和ImportSelector
-
如@EnableAspectJAutoProxy通过ImportBeanDefinitionRegistrar实现,注册AnnotationAwareAspectJAutoProxyCreator。
-
@EnableTransactionManagement通过ImportSelector(如TransactionManagementConfigurationSelector)选择需要的事务配置类。
4. 源码解析
ConfigurationClassPostProcessor负责处理@Configuration类,通过ConfigurationClassParser解析配置类及其导入的源码笔记24类,然后由ConfigurationClassBeanDefinitionReader注册BeanDefinition。处理@Import时,通过深度优先搜索避免循环导入。 解析过程中,配置类的递归导入需防止环形依赖,通过导入链映射表判断。此外,还考虑了内部配置类递归导入外部类的情况。5. ImportBeanDefinitionRegistrar和ImportSelector的行为
-
导入注册器和选择器时,会提前触发Aware接口方法,并在BeanDefinition注册时执行注册方法。
-
DeferredImportSelector处理时机独特,但处理逻辑与普通选择器类似,只是在解析末尾进行。
总结
@Configuration的@Import提供了丰富的导入方式,展现了灵活性。源码中的处理策略确保了解析过程的稳定性和效率,体现了Spring框架的精细设计和用户自定义的便捷性。SpringBoot源码学习——SpringBoot自动装配源码解析+Spring如何处理配置类的
SpringBoot通过SPI机制,借助外部引用jar包中的META-INF/spring.factories文件,实现引入starter即可激活功能,简化手动配置bean,实现即开即用。
启动SpringBoot服务,通常使用Main方法启动,其中@SpringBootApplication注解包含@SpringBootConfiguration、@EnableAutoConfiguration、007溯源码@ComponentScan,自动装配的核心。
深入分析@SpringBootApplication,其实质是执行了@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan三个注解的功能,简化了配置过程,强调了约定大于配置的思想。
SpringBoot的自动装配原理着重于研究如何初始化ApplicationContext,Spring依赖于ApplicationContext实现其功能,SpringApplication#run方法为初始化ApplicationContext的入口。
分析SpringApplication构造方法,SpringApplication.run(启动类.class, args) 实际调用的是该方法,其关键在于根据项目类型反射生成合适的ApplicationContext。
选择AnnotationConfigServletWebServerApplicationContext,此上下文具备启动Servlet服务器和注册Servlet或过滤器类型bean的能力。
准备刷新ApplicationContext,SpringBoot将主类注册到Spring容器中,以便@ConfigurationClassPostProcessor解析主类注解,发挥@Import、@ComponentScan的作用。
刷新ApplicationContext过程包括一系列前置准备,如将主类信息封装成AnnotatedGenericBeanDefinition,解析注解并调用BeanDefinitionCustomizer自定义处理。
解析配置类中的注解,通过BeanDefinitionRegistryPostProcessor和ConfigurationClassParser实现,筛选、合力指标源码排序候选者,并解析@Import注解实现自动装配。
增强配置类,ConfigurationClassPostProcessor对full模式的配置进行增强,确保@Import正确处理,CGLIB用于增强原配置类,确保生命周期完整,避免真正执行@Bean方法逻辑。
深入解析AutoConfigurationImportSelector实现自动装配,通过spring.boot.enableautoconfiguration设置开启状态,读取spring-autoconfigure-metadata.properties和META-INF/spring.factories文件,筛选并加载自动配置类。
SpringCloud原理OpenFeign原来是这么基于Ribbon来实现负载均衡的
大家好,本文将深入探讨 SpringCloud 组件原理,特别是 OpenFeign 如何基于 Ribbon 实现负载均衡的机制。在此前的文章中,我们已详细解析了 OpenFeign 动态代理生成原理及 Ribbon 运行机制,如需回顾相关知识,欢迎关注微信公众号 “三友的java日记”,通过菜单栏查看整理内容。接下来,我们将进一步揭示 OpenFeign 与 Ribbon 如何协同工作,实现高效负载均衡。一、Feign 动态代理调用实现 rpc 流程分析
通过了解 Feign 客户端接口的动态代理生成原理,我们得知动态代理基于 JDK 的机制实现,所有方法调用最终通过 InvocationHandler 接口的 ReflectiveFeign.FeignInvocationHandler 实现。接下来,我们将探讨 FeignInvocationHandler 如何执行 rpc 调用。 FeignInvocationHandler 中的 invoke 方法实现关键步骤如下:前几行判断方法是否为 equals、hashCode、toString 等不需要走 rpc 调用的特殊方法。
从 dispatch 获取对应方法的 MethodHandler,然后调用 MethodHandler 的 invoke 方法。MethodHandler 的生成发生在构建动态代理时。
MethodHandler 是接口的实现类,分为 DefaultMethodHandler(处理接口默认方法)和 SynchronousMethodHandler(实现 rpc 调用)。我们接下来关注 SynchronousMethodHandler 中的 invoke 方法实现。 SynchronousMethodHandler 的 invoke 方法包含关键步骤:构建 RequestTemplate,用于封装构建 HTTP 请求所需的参数,如头信息和 body 等。
调用 findOptions(argv) 方法获取连接超时时间和读超时时间配置。如果没有配置,将使用构建 SynchronousMethodHandler 时传入的参数。
执行重试组件(通常不设置重试逻辑)。
执行 executeAndDecode(template, options),进入此方法后执行 targetRequest,遍历所有请求拦截器(Feign 的扩展点),允许在发送请求前进行参数调整,如添加请求头,这在微服务间鉴权时常用。
之后,构造请求并调用 Client 接口的 execute 方法发送请求,接收响应,并将响应数据封装为所需参数返回给调用方。二、LoadBalancerFeignClient
在理解整个动态代理调用流程后,我们发现关键在于 Client 接口的实现,负责发送 HTTP 请求。那么,Client 是什么?在关于 OpenFeign 动态代理生成的文章中,我们探讨了 Feign 在构建动态代理时填充组件到 Feign.Builder 的过程,其中包含 Client 的实现,但并未在 FeignClientsConfiguration 配置类中找到 Client 对象的声明。这提示我们,Client 实现依赖于负载均衡,是 Feign 整合 Ribbon 的入口。 接下来,我们将聚焦于 Client 的实现,特别是 Feign 如何利用 Ribbon 实现负载均衡。 首先,我们查看 Feign 与 Ribbon 整合的配置类,该类导入了关键配置类。其中,DefaultFeignLoadBalancedConfiguration 配置类声明了 LoadBalancerFeignClient 到 Spring 容器中,传入了 Client 实现、CachingSpringLoadBalancerFactory 和 SpringClientFactory。 LoadBalancerFeignClient 实现了 Client 接口,构建 Feign.Builder 时注入的是这个对象。接下来,我们深入分析构造 LoadBalancerFeignClient 的实现流程。 动态代理调用过程中得出结论,最终会调用 Client 接口的 execute 方法,因此,我们关注 execute 方法的实现。此方法包含一系列操作,从请求 URL 中获取 clientName(服务名),并利用 OpenFeign 构建动态代理时传入的 HardCodedTarget 从 URL 中提取服务名。获取服务名后,LoadBalancerFeignClient 调用 lbClient 方法。 lbClient 方法实现关键步骤,首先从缓存中获取或创建 FeignLoadBalancer,然后利用 CachingSpringLoadBalancerFactory 的 create 方法构建 FeignLoadBalancer。 FeignLoadBalancer 实现关键逻辑,调用 executeWithLoadBalancer 方法处理请求,接收 Response 后直接返回。三、FeignLoadBalancer
FeignLoadBalancer 是关键组件,负责负载均衡和 HTTP 请求的发送。它继承 AbstractLoadBalancerAwareClient,实现了核心功能。 FeignLoadBalancer 的 execute 方法包含关键步骤,直接定位到核心代码行,request.client() 获取注入的 Client 实现,即 Client.Default 类或基于 HttpClient 或 OkHttp 的实现。调用此行代码成功发送 HTTP 请求,接收响应后封装成 RibbonResponse,最终返回给 MethodHandler,解析响应并封装为方法的返回值。总结
通过本文,我们完整解析了 OpenFeign、Ribbon 和 Nacos(或其他注册中心)协同工作原理,涵盖五个关键组件的源码和流程。简而言之,OpenFeign 在进行 rpc 调用时,由于服务所在机器未知,Ribbon 负责从机器列表中选择一个,该列表由注册中心提供。Ribbon 的 ServerList 接口允许注册中心实现,获取服务机器列表。通过这三个组件的协同作用,实现了微服务架构中的高效负载均衡。 本文旨在帮助读者了解微服务架构的基本原理,同时深入理解 OpenFeign、Ribbon 和 Nacos 的源码。如有疑问或交流需求,欢迎关注微信公众号 “三友的java日记” 或添加微信 ZZYNKXJH 联系作者。感谢阅读,期待与您在下篇文章中相遇。Spring IoC源码深度剖析
Spring IoC容器初始化深度剖析
Spring IoC容器是Spring的核心组件,主要负责对象管理和依赖关系管理。容器体系丰富多样,如BeanFactory作为顶层容器,它定义了所有IoC容器的基本原则,而ApplicationContext及其子类如ClassPathXmlApplicationContext和AnnotationConfigApplicationContext则提供了额外功能。Spring IoC容器的初始化流程关键在AbstractApplicationContext的refresh方法中。 1.1 初始化关键点 通过创建特定类LagouBean并设置断点,我们发现Bean的创建在未设置延迟加载时,发生在容器初始化过程中。构造函数调用、InitializingBean的afterPropertiesSet方法以及BeanFactoryPostProcessor和BeanPostProcessor的初始化和调用,都在refresh方法的不同步骤中发生。 1.2 主体流程概览 Spring IoC容器初始化的主体流程主要集中在AbstractApplicationContext的refresh方法,涉及Bean对象创建、构造函数调用、初始化方法执行和处理器调用等步骤。 1.3 深度剖析 分析发现,延迟加载机制使得懒加载的bean在第一次调用getBean时才进行初始化。而对于非懒加载bean,它们在容器初始化阶段已经完成并缓存。Spring处理循环依赖的方法依赖于构造器调用的顺序规则,不支持原型bean的循环依赖,而对单例bean则通过setXxx或@Autowired方法提前暴露对象来避免循环依赖。2024-12-23 23:02
2024-12-23 22:39
2024-12-23 22:25
2024-12-23 22:03
2024-12-23 22:02