创建前的准备:Spring需要拿到需要被创建的Bean定义(Bean之间的依赖关系,类信息等),将这些类信息放在Spring中的集合中。
实施创建:
一、实例化对象(普通对象):
> 在Spring中,**Bean的创建顺序是由Bean的依赖关系决定的**。当容器启动时,它会根据Bean的定义和依赖关系创建和初始化Bean。如果一个Bean依赖于其他Bean,那么它会在依赖的Bean之后被创建。
这个过程Spring会通过反射方式拿到Bean的构造方法,再通过构造方法去创建一个普通对象,
具体通过哪一个构造器去创建对象?
分情况说明:
A、类中只有一个构造器,就使用这个构造器
B、类中有多个构造器:优先选择被@Autowried指定的构造器 否则-->Spring默认使用无参构造器 否则-->使用类中唯一的构造器,(**如果你既没有为Spring指定需要使用的构造器,也没有无参构造器,在这种情况下,你居然有多个构造器,Spring将不知道该使用哪一个构造器去为你创建对象,那么程序将报错**),实例化普通对象失败。所以说,想要Spring帮你创建一个对象,那么你的类需要满足的条件是: 为Spring指定构造器 or 有无参构造器 or 有且仅有一个有参构造器。
二、依赖注入
依赖注入(Dependency Injection)是一种软件设计模式,它用于解耦组件之间的依赖关系。在依赖注入中,组件的依赖关系不由组件自身来创建或管理,而是由外部的容器来负责创建和注入依赖。
具体来说,依赖注入通过将依赖关系作为参数传递给组件的构造函数、方法或属性来实现。这样,组件无需自己创建或查找依赖,而是通过外部容器提供的依赖注入机制来获取所需的依赖对象。
依赖注入的优点包括:
- 解耦性:依赖注入减少了组件之间的直接依赖,使得组件更加独立和可复用。
- 可测试性:通过依赖注入,可以轻松地替换组件的依赖对象,从而方便进行单元测试。
- 可扩展性:依赖注入使得组件的依赖关系更加灵活,可以方便地添加、替换或移除依赖。
- 可维护性:依赖注入将组件的依赖关系集中管理,使得代码更加清晰和易于维护。
总而言之,依赖注入是一种通过外部容器来管理组件依赖关系的设计模式,它提高了代码的灵活性、可测试性和可维护性。
Spring中的依赖注入可以理解成为上个阶段实例化出来的对象填充属性,哪些属性呢?被@Autowired修饰的属性,这些属性也是交付于Spring管理的Bean,直接从Spring容器中去获取,如果找不到程序报错。一旦注入成功,这时候你的普通对象才会变成一个Bean。普通对象和Bean其实是同一个对象,只是成为Bean的普通对象更为完整,就好像一个人从儿童时期成长为少年时期一样,拥有的特性可能会丰富一些,但实际上人还是这个人。
三、Bean的初始化
通过上面两个步骤,已经完成了一个对象的属性填充(这里说的属性填充,并不是说所有的属性都已经被Spring填充了,只是那些被@Autowired修饰的被填充,即:被告知需要Spring去帮你填充的属性。你会发现,不论是构造器还是属性注入,@Autowired实际上有一种通知、指定的意思在里头。因此可以这么理解:@Autowired注解就是告诉Spring,这个事情要你来帮我做)。
对象的属性都被处理了,那么对象的方法呢?大概也是同样的道理,Spring会去执行处理那些被告知要处理的方法,只是通知的方式可能会有些不同。大概来说有:
A、使用@PostConstruct修饰,
B、这个Bean所属类实现InitializingBean接口并且定义afterPropertiesSet()方法;(A.B都是在初始化之前执行,且@PostConstruct优先级较高一些)
C、程序员自己定义的一些BPP操作(分为初始化之前和初始化之后的操作,目的都是对Bean进行一些拓展),请注意:这些情况可以是同时存在的,只是有一定的执行优先级,具体可以通过Cat GPT来查询,总的来说,在Bean初始化过程的一些操作还是比较丰富的,比较要丰富一个对象,对Bean进行拓展还是需要一些复杂的操作的,
补充:在这个过程中,Spring还会对容器进行一定的初始化,因为有些Bean因为实现了ApplicationContextAware接口,它可能有一些方法的实现需要容器的信息(比如容器名称之类的),所以Spring要将容器开启可以被Bean获取信息的功能(大概可以这么理解)。
四、将创建好的Bean对象放入Map(确保Bean是单例的)
Spring中的Bean默认都是单例的,即,当你通过BeanName去获取Bean对象时,拿到的Bean对象始终是唯一的,Spring中实现原理是:将创建好的Bean存放入Map集合中。Map中key保存Bean的名称,vlaue保存实际的Bean对象,根据Map集合中key值不能重复原理,就能实现在通过BeanName去获取Bean对象时获取到的只有一个对象。值得一提的是:请注意这里的单例针对的是Bean的name,而不是BeanType,容器中可以出现多个类型相同但是名字不同的Bean。
本文介绍了Spring框架中Bean的创建过程。首先要准备好Bean定义并放入集合,接着进行创建,包括实例化对象,根据类构造器情况选择创建方式;依赖注入,解耦组件依赖;Bean初始化,处理对象方法;最后将创建好的Bean放入Map确保单例。

1万+

被折叠的 条评论
为什么被折叠?



