Spring - 源码分析:Spring是如何把Bean注册到IOC容器中的?(下)

简介: Spring - 源码分析:Spring是如何把Bean注册到IOC容器中的?(下)

注解方式下Bean的注册

前面我们讲到xml配置文件进行Bean的注册,xml配置是Spring早期常用的配置方式,现在基本上大部分场景上都推荐使用注解的方式,尤其是SpringBoot时代的来临,进一步推动了注解方式的全面使用,下面我们来看看注解方式下的Bean注册,还是从个简单的例子入手

@ComponentpublicclassAnnotionConfig {
@Bean(name="userBean")
publicUsergetUserBean(){
Useruser=newUser();
user.setUserName("Lucy");
returnuser;
    }
}
publicclassAnnotionBeanTest {
publicstaticvoidmain(String[] args){
AnnotationConfigApplicationContextapplicationContext=newAnnotationConfigApplicationContext("org.kxg.springDemo");
Useruser= (User) applicationContext.getBean("userBean");
System.out.println(user.getUserName());
    }
}


这里用到AnnotationConfigApplicationContext,是另外一种容器的实现,传入一个包名,会自动扫描包下面的Spring注解,然后将其注册到容器中


publicAnnotationConfigApplicationContext(String... basePackages) {
this();
//主要是scan方法完成bean的注册scan(basePackages);
//又到了这个方法,有没有很熟悉~~~refresh();
}


下面我们重点看一下注解方式的Bean注册


publicintscan(String... basePackages) {
intbeanCountAtScanStart=this.registry.getBeanDefinitionCount();
//扫描包,进行Bean注册doScan(basePackages);
// Register annotation config processors, if necessary.if (this.includeAnnotationConfig) {
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }
return (this.registry.getBeanDefinitionCount() -beanCountAtScanStart);
}


//ClassPathBeanDefinitionScannerprotectedSet<BeanDefinitionHolder>doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder>beanDefinitions=newLinkedHashSet<>();
for (StringbasePackage : basePackages) {
//扫描包下打了注解的类,并将其转换成BeanDefinitionSet<BeanDefinition>candidates=findCandidateComponents(basePackage);
for (BeanDefinitioncandidate : candidates) {
ScopeMetadatascopeMetadata=this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
StringbeanName=this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidateinstanceofAbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
            }
if (candidateinstanceofAnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
            }
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolderdefinitionHolder=newBeanDefinitionHolder(candidate, beanName);
definitionHolder=AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
//进行BeanDefinition注册registerBeanDefinition(definitionHolder, this.registry);
            }
        }
    }
returnbeanDefinitions;
}


publicstaticvoidregisterBeanDefinition(
BeanDefinitionHolderdefinitionHolder, BeanDefinitionRegistryregistry)
throwsBeanDefinitionStoreException {
// Register bean definition under primary name.StringbeanName=definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.String[] aliases=definitionHolder.getAliases();
if (aliases!=null) {
for (Stringalias : aliases) {
registry.registerAlias(beanName, alias);
        }
    }
}


看到这个方法,有没有点眼熟的感觉


上面xml方式进行Bean注册也调用到这个方法了,所以后面的流程都是一样的,注解方式和xml配置方式从本质上来讲,并没有什么不同,只是Bean的描述不同而已,最终都会被解析成BeanDefinition,注册到容器中,至此整个Bean的注册流程就已经完了。


当然在整个过程中,忽略了很多细节,只看了主线流程。


读源码的时候,很容易陷入细节中,尤其是像Spring这样通用的框架,它为了通用性和扩展性,会把代码写的很“绕”,如果你过于关注细节很容易让自己陷入实现的细节中,一开始看源码的时候,建议不用太关注细节,把主线功能先看完,知道大概的原理后再逐个去击破~

目录
相关文章
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
1059 26
|
9月前
|
XML Java 测试技术
《深入理解Spring》:IoC容器核心原理与实战
Spring IoC通过控制反转与依赖注入实现对象间的解耦,由容器统一管理Bean的生命周期与依赖关系。支持XML、注解和Java配置三种方式,结合作用域、条件化配置与循环依赖处理等机制,提升应用的可维护性与可测试性,是现代Java开发的核心基石。
|
XML Java 数据格式
Spring IoC容器的设计与实现
Spring 是一个功能强大且模块化的 Java 开发框架,其核心架构围绕 IoC 容器、AOP、数据访问与集成、Web 层支持等展开。其中,`BeanFactory` 和 `ApplicationContext` 是 Spring 容器的核心组件,分别定位为基础容器和高级容器,前者提供轻量级的 Bean 管理,后者扩展了事件发布、国际化等功能。
394 18
|
XML Java 数据格式
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
监控 Java 应用服务中间件
SpringBoot是如何简化Spring开发的,以及SpringBoot的特性以及源码分析
Spring Boot 通过简化配置、自动配置和嵌入式服务器等特性,大大简化了 Spring 应用的开发过程。它通过提供一系列 `starter` 依赖和开箱即用的默认配置,使开发者能够更专注于业务逻辑而非繁琐的配置。Spring Boot 的自动配置机制和强大的 Actuator 功能进一步提升了开发效率和应用的可维护性。通过对其源码的分析,可以更深入地理解其内部工作机制,从而更好地利用其特性进行开发。
647 6
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
507 12
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
623 12
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
588 6
|
XML Java 数据格式
🌱 深入Spring的心脏:Bean配置的艺术与实践 🌟
本文深入探讨了Spring框架中Bean配置的奥秘,从基本概念到XML配置文件的使用,再到静态工厂方式实例化Bean的详细步骤,通过实际代码示例帮助读者更好地理解和应用Spring的Bean配置。希望对你的Spring开发之旅有所助益。