Spring源码从入门到精通---@Import(五)
深入解析如何给容器注册bean
通过ComponentScan+注解如@Controller,源码@Service,@Compoment,@Repository实现自动扫描bean
@Bean+@Configuration定义导入第三方bean
利用@Import快速批量导入组件,优势在于简化配置
文章重点解析@Import的容器三种用法:直接导入容器、自定义importSelector实现、源码自定义ImportBeanDefinitionRegistrar手动注册
1)@import注解直接导入容器,容器id默认为全类名
2) 自定义importSelector类,源码返回需要注册的容器疫情诉源码怎么下载全类名数组
3) 实现ImportBeanDefinitionRegistrar接口,自定义组件注册和id
通过@Import源码,源码导入的容器实质是一个数组,允许批量导入多个类
演示通过import将组件如color和red导入容器,源码并展示容器中组件的容器打印
提供JUnit测试类,重复利用方法提取getDefinitionNames(),源码简化测试步骤
新增1)@Import基础使用部分,容器删除原有代码,源码便于理解@Import
运行示例,容器展示导入组件后的源码容器打印结果,突出import的优势
详细步骤:
2)自定义myImportSelector类实现ImportSelector,返回新增组件路径,结合扫描自定义类
结果展示:blue和yellow组件成功注册容器,验证自定义importSelect功能
3)实现ImportBeanDefinitionRegistrar接口,自定义组件名注册到容器
junit测试不变,运行结果:验证容器中包含red、yellow组件,满足自定义id需求
Spring源码系列-BeanPostProcessor与BeanFactoryPostProcessor
在Spring框架中,BeanPostProcessor与BeanFactoryPostProcessor各自承担着不同的职责,它们在IoC容器的工作流程中起着关键作用。
BeanFactoryPostProcessor作用于BeanDefinition阶段,对容器中Bean的定义进行处理。这个过程发生在BeanFactory初始化时,sar函数源码对BeanDefinition进行修改或增强,提供了一种在不修改源代码的情况下定制Bean的机制。相比之下,BeanPostProcessor则在Bean实例化之后生效,对已经创建的Bean对象进行进一步处理或替换,提供了更晚、更灵活的扩展点。
以制造杯子为例,BeanFactoryPostProcessor相当于在选择材料和形状阶段进行定制,而BeanPostProcessor则在杯子制造完成后,进行诸如加花纹、抛光等深加工。
在Spring框架中,BeanPostProcessor的使用场景较为广泛,尤其在实现AOP(面向切面编程)时,通过使用代理类替换原始Bean,实现如日志记录、事务管理等功能。
此外,容器在启动后,还会进行消息源初始化、广播器初始化及监听器初始化,为Bean实例化做好准备。完成这些准备工作后,容器会调用registerBeanPostProcessors方法注册BeanPostProcessor,对已创建的Bean进行进一步处理。同时,app源码定制初始化消息源、广播器和监听器,为后续事件处理做好基础。
总结,BeanFactoryPostProcessor与BeanPostProcessor在Spring IoC容器中的作用各有侧重。前者侧重于对BeanDefinition的定制,后者则是在Bean实例化后的进一步加工,两者共同为构建灵活、可扩展的IoC容器提供了强大的支持。
在深入分析Spring框架的源码时,我们发现refresh()方法的实现中包含了对BeanFactoryPostProcessor和BeanPostProcessor的注册与处理。这些处理步骤确保了容器能够在启动时对Bean进行正确的配置和初始化。
文章中通过一个例子展示了如何使用BeanFactoryPostProcessor替换已注册Bean的实现,以及对其源码的分析。通过例子和源码的结合,读者能够更直观地理解这些后置处理器在Spring框架中的应用和工作原理。
Spring容器之refresh方法源码分析
Spring容器的核心接口BeanFactory与ApplicationContext之间的关系是继承,ApplicationContext扩展了BeanFactory的功能,提供了初始化环境、参数、后处理器、事件处理以及单例bean初始化等更全面的服务,其中refresh方法是Spring应用启动的入口点,负责整个上下文的准备工作。 让我们深入分析AbstractApplicationContext#refresh方法在启动过程中的具体操作:准备刷新阶段: 包括系统属性和环境变量的检查和准备。
获取新的BeanFactory: 初始化并解析XML配置文件。
customizeBeanFactory: 个性化BeanFactory设置,天神传 源码如覆盖定义、处理循环依赖等。
loadBeanDefinitions: 通过解析XML文件,创建BeanDefinition对象并注入到容器中。
填充BeanFactory功能: 设置classLoader、表达式语言处理器,增强Aware接口处理,添加AspectJ支持和默认系统环境bean等。
激活BeanFactory后处理器: 分为BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor,分别进行BeanDefinition注册和BeanFactory增强。
注册BeanPostProcessors: 拦截Bean创建的后处理器,按优先级注册。
初始化其他组件: 包括MessageSource、ApplicationEventMulticaster和监听器。
初始化非惰性单例: 预先实例化这些对象。
刷新完成: 通知生命周期处理器并触发ContextRefreshedEvent。
以上是refresh方法在Spring应用启动流程中的关键步骤。以上内容仅为个人理解,如需更多信息,可参考CSDN博客链接。Spring IoC源码深度剖析
Spring IoC容器初始化深度剖析
Spring IoC容器是Spring的核心组件,主要负责对象管理和依赖关系管理。容器体系丰富多样,如BeanFactory作为顶层容器,它定义了所有IoC容器的基本原则,而ApplicationContext及其子类如ClassPathXmlApplicationContext和AnnotationConfigApplicationContext则提供了额外功能。Spring IoC容器的javac源码下载初始化流程关键在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方法提前暴露对象来避免循环依赖。ç»èSpring-
1ãä»ä¹æ¯Spring
Springå°±æ¯ä¸ä¸ªjavaåçæ¡æ¶ï¼ä½¿ç¨javaè¯è¨å¼åçï¼ è½»é级çï¼ å¼æºçæ¡æ¶ã å¯ä»¥å¨j2seãj2ee项ç®ä¸é½å¯ä»¥ä½¿ç¨ã
Springæ ¸å¿ææ¯ï¼ iocï¼ aop
Springåå«åï¼å®¹å¨ï¼ springä½ä¸ºå®¹å¨ï¼ è£ çæ¯java对象ã å¯ä»¥è®©springå建javaå¯¹è±¡ï¼ ç»å±æ§èµå¼ã
Springä½ç¨ï¼ å®ç°è§£è¦åï¼ è§£å³java对象ä¹é´çè¦åï¼ è§£å³æ¨¡åä¹é´çè¦åã
æ»ç»ï¼ Springæ大çç¹ç¹å°±æ¯å¸®ä½ å建对象ï¼ä¸éè¦ä½ å¨ä»£ç ä¸æå¨çå»newï¼èæ¯åªè¦ä½ åè¯Springç容å¨ï¼ä½ è¦ç对象çååï¼Spring容æå°±ä¼èªå¨ç»ä½ äºã就好æ¯å¦ä½ æ³åä¸ä¸ªä¸è¥¿ï¼ä½ ä¸éè¦èªå·±æå¨çå»åï¼ä½ å¯ä»¥å»é¤å éé¢ï¼åè¯æå¡åä½ æ³åçèçååï¼é£ä¹æå¡åå°±å¯ä»¥ç»ä½ ä¸èäºã
Springä¹åä¸èèªç©ºæ¯è°ï¼è½ç¶å®æ¬èº«æ²¡æä»ä¹ä½æè½åãä½æ¯å®çç²æ¿ä¸å¯ä»¥å®¹çº³å¾å¤è°è½½æºï¼å ·ä½ä½æä»»å¡å¯ä»¥è®©è¿äºè°è½½æºå»æ§è¡ãè°è½½æºå°±åæ¯å ¶å®æ¡æ¶çæ ¸å¿å¯¹è±¡ï¼æ¯å¦nybatisçSqlSession对象ãSpringå¯ä»¥ç®¡çè¿äºæ ¸å¿ç对象ã
2ãSpringçæç¹
Spring æ¯ä¸ä¸ªæ¡æ¶ï¼æ¯ä¸ä¸ªåæåç软件ãæ 个模åç»æãå®æ¯ä¸ä¸ªå®¹å¨ç®¡ç对象ï¼å®¹å¨æ¯è£ ä¸è¥¿çï¼Spring 容å¨ä¸è£ ææ¬ï¼æ°åãè£ çæ¯å¯¹è±¡ãSpring æ¯åå¨å¯¹è±¡ç容å¨ã
ï¼1ï¼ è½»é Spring æ¡æ¶ä½¿ç¨ç jar é½æ¯è¾å°ï¼ä¸è¬å¨ 1M 以ä¸æè å ç¾ kbãSpringæ ¸å¿åè½çæéç jar æ»å ±å¨ 3M å·¦å³ã Spring æ¡æ¶è¿è¡å ç¨çèµæºå°ï¼è¿è¡æçé«ãä¸ä¾èµå ¶ä» jar
ï¼2ï¼ é对æ¥å£ç¼ç¨ï¼è§£è¦å Spring æä¾äº Ioc æ§å¶å转ï¼ç±å®¹å¨ç®¡ç对象ï¼å¯¹è±¡çä¾èµå ³ç³»ãåæ¥å¨ç¨åºä»£ç ä¸ç对象å建æ¹å¼ï¼ç°å¨ç±å®¹å¨å®æã对象ä¹é´çä¾èµè§£è¦åã
ï¼4ï¼ æ¹ä¾¿éæåç§ä¼ç§æ¡æ¶ Spring ä¸ææ¥åç§ä¼ç§çå¼æºæ¡æ¶ï¼ç¸å Spring å¯ä»¥éä½åç§æ¡æ¶ç使ç¨é¾åº¦ï¼Spring æä¾äºå¯¹åç§ä¼ç§æ¡æ¶ï¼å¦ Struts,HibernateãMyBatisï¼ççç´æ¥æ¯æãç®åæ¡æ¶ç使ç¨ãSpring åæ线æ¿ä¸æ ·ï¼å ¶ä»æ¡æ¶æ¯æ头ï¼å¯ä»¥å®¹æçç»åå°ä¸èµ·ãéè¦ä½¿ç¨åªä¸ªæ¡æ¶ï¼å°±æè¿ä¸ªæ头æ¾å ¥æ线æ¿ãä¸éè¦å¯ä»¥è½»æç移é¤ã
3ãIoC æ§å¶å转
3.1IoCå为 æ§å¶åå转
å转ï¼æå¼å人å管ç对象çæé转移ç»äºä»£ç ä¹å¤ç容å¨å®ç°ã ç±å®¹å¨å®æ对象ç管çã
æ£è½¬ï¼å¼å人åå¨ä»£ç ä¸ï¼ ä½¿ç¨ new æé æ¹æ³å建对象ã å¼å人åææ¡äºå¯¹è±¡çå建ï¼å±æ§èµå¼ï¼å¯¹è±¡ä»å¼å§å°éæ¯çå ¨é¨è¿ç¨ã å¼å人åæ对 对象 å ¨é¨æ§å¶ã
éè¿å®¹å¨ï¼å¯ä»¥ä½¿ç¨å®¹å¨ä¸ç对象ï¼å®¹å¨å·²ç»å建äºå¯¹è±¡ï¼ 对象å±æ§èµå¼äºï¼ 对象ä¹ç»è£ 好äºï¼ã
Springå°±æ¯ä¸ä¸ªå®¹å¨ï¼å¯ä»¥ç®¡ç对象ï¼å建对象ï¼ç»å±æ§èµå¼ã
3.1IoCçææ¯å®ç°
DI ï¼ ä¾èµæ³¨å ¥ï¼ ï¼Dependency Injectionï¼ ç¼©åæ¯DI . æ¯IoCçä¸ç§ææ¯å®ç°ã ç¨åºåªéè¦æä¾è¦ä½¿ç¨ç对象çå称就å¯ä»¥äºï¼ 对象å¦ä½åå»ºï¼ å¦ä½ä»å®¹å¨ä¸æ¥æ¾ï¼è·åé½ç±å®¹å¨å é¨èªå·±å®ç°ã
Springæ¡æ¶ä½¿ç¨çDIå®ç°IoC.éè¿springæ¡æ¶ï¼ åªéè¦æä¾è¦ä½¿ç¨ç对象åè¯å°±å¯ä»¥äºã ä»å®¹å¨ä¸è·åå称对åºç对象ãspringåºå±ä½¿ç¨ç åå°æºå¶ï¼ éè¿åå°å建对象ï¼ç»å±æ§ã
Spring源码- Spring IoC容器启动之refresh方法
在注册阶段,AnnotationConfigApplicationContext构造方法中的第一个方法被分析过。接下来,我们关注第二个方法:register(componentClasses)。在使用XML配置方式时,通过new ClassPathXmlApplicationContext("classpath:spring.xml")来创建实例,其中需要指定xml配置文件路径。使用注解方式时,也需要为ApplicationContext提供起始配置源头,这里使用配置类代替xml配置文件,按照配置类中的注解(如@ComponentScan、@Import、@Bean)解析并注入Bean到IoC容器。
通过配置类,Spring解析注解实现Bean的注入。使用@Configuration注解定义的配置类相当于xml配置文件,但目前Spring推荐使用注解方式,xml配置的使用概率正在降低。
register(componentClasses)方法的核心逻辑在AnnotatedBeanDefinitionReader#doRegisterBean中,将传入的配置类解析为BeanDefinition并注册到IoC容器。ConfigurationClassPostProcessor这个BeanFactory后置处理器在IoC初始化时,获取配置类的BeanDefinition集合,开始解析。
真正启动IoC容器的流程在refresh()方法中,这是了解IoC容器启动流程的关键步骤。refresh方法在AbstractApplicationContext中定义,采用模板模式,提供IoC初始化流程的基本实现,子类可以扩展。
下面分析refresh()方法的每个步骤,以了解IoC容器的启动流程。
prepareRefresh方法主要在refresh执行前进行准备工作,如设置Context的启动时间、状态,以及扩展系统属性相关。
initPropertySources()方法主要用于扩展配置来源,如网络、物理文件、数据库等加载配置信息。StandardEnvironment默认只提供加载系统变量和应用变量的功能,用于子类扩展。
❝initPropertySources方法常见扩展场景包括:❞
getEnvironment().validateRequiredProperties()确保设置的必要属性在环境中存在,否则抛出异常终止应用。
BeanFactory是Spring的基本IoC容器,ApplicationContext包装了BeanFactory,提供更智能、更便捷的功能。ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();获取的BeanFactory是IoC容器初始化工作的基础。
上面获取的BeanFactory还不能直接使用,需要填充必要的配置信息。至此,IoC容器的启动流程基本完成。
这里对IoC启动流程有个大致、直观的印象。主要步骤包括:准备阶段、配置来源扩展、初始化BeanFactory、填充配置、解析配置类、注册Bean、实例化BeanPostProcessor、初始化国际化和事件机制、以及创建内嵌Servlet容器(在SpringBoot中实现)。这些步骤确保了IoC容器顺利启动并管理Bean。
SpringBoot源码之容器刷新 refreshContext 方法详解
深入探索 SpringBoot 容器刷新机制,重点解析 refreshContext 方法,引领你步入 SpringBoot 源码的神秘殿堂。
刷新容器,首先进入 prepareRefresh 方法,为后续流程铺垫。
随后,obtainFreshBeanFactory 方法展开,围绕 DefaultListableBeanFactory 类,确保 Bean 加载与注册的顺利进行。
准备 BeanFactory,通过 prepareBeanFactory 方法,为所有 Bean 的加载与注册工作做好铺垫。
postProcessBeanFactory 方法加入后置处理器,确保 BeanFactory 的最终配置与校验。
invokeBeanFactoryPostProcessors 方法启动,对所有已定义的扩展点进行加载,包括 BeanFactoryPostProcessorPoint 和 BeanDefinitionRegistryPostProcessorPoint,丰富 Spring 的功能。
注册监听器与系统事件,onRefresh 方法负责,通过 ApplicationListener 对象,执行事件的广播与响应。
finishBeanFactoryInitialization 方法,聚焦于 singleton beans 的初始化,确保单例 Bean 的正确创建与配置。
preInstantiateSingletons 方法,对 BeanFactory 中的实例进行预实例化处理,确保懒加载 Bean 的正常启动。
深入getBean方法,解析 Bean 的创建与属性注入过程,从类型与名称注入,到回调处理,每一个细节都不可或缺。
属性注入完成,意味着 Bean 的初始化工作接近尾声,通过回调机制,观察扩展点的丰富性与灵活性。
总结,SpringBoot 的容器刷新机制,不仅高效管理 Bean 的生命周期,还通过扩展点的灵活配置,为开发者提供了强大的自定义能力。
本文仅作为 SpringBoot 容器刷新方法的初步解析,期待后续文章深入探讨扩展点的实现与应用,如有任何疑问或错误,欢迎指正。
参考来源:javadoop.com/post/spring...
Spring容器刷新——obtainFreshBeanFactory
本文讨论的是Spring容器中的刷新过程,重点讲解了创建BeanFactory实例的操作。BeanFactory和ApplicationContext在Spring源码中有多种实现,ApplicationContext在BeanFactory基础上增加了额外功能,如管理应用上下文、提供更丰富的依赖注入等。
在实际应用中,选择使用哪个具体实现取决于项目的特定需求。本文列出了两种常见的实现:AbstractApplicationContext和GenericApplicationContext。
AbstractApplicationContext支持多次刷新,内部维护了一个volatile的DefaultListableBeanFactory实例。刷新逻辑分为两步:首先调用refreshBeanFactory()方法,然后返回此实例通过getBeanFactory()方法。
GenericApplicationContext的实现相对简单,对于obtainFreshBeanFactory()方法的调用几乎不做任何操作。
至于应用程序中使用哪个具体的BeanFactory实现,这取决于项目的配置和需求。在传统的Servlet环境下,通常通过ContextLoaderListener加载上下文,而SpringBoot环境中的ApplicationContext创建则通过ApplicationContextFactory完成。
具体实现细节和流程在不同环境下的差异,如Servlet环境中的ContextLoaderListener和ContextLoader的使用,以及SpringBoot环境中的ApplicationContextFactory的实现,将在后续的文章中进行详细阐述。
2024-12-22 21:53
2024-12-22 21:18
2024-12-22 20:52
2024-12-22 20:49
2024-12-22 20:07