文章参考来源:Spring Framework官方文档
-
Spring容器的核心jar包是:org.springframework.beans和org.springframework.context
-
BeanFactory提供了配置框架和基本功能,而ApplicationContext是BeanFactory的子接口,添加了更多特定于企业的功能,它是BeanFactory的一个完整超集。
-
org.springframework.context.ApplicationContext接口代表了Spring IoC容器,它负责实例化,配置并组装beans。
-
容器通过读取”配置元数据“去知道哪些对象需要被实例化/配置/组装。”配置元数据“的格式可以是XML、Java注释或Java代码。
无论是使用XML、Java注释或Java代码,都能够满足用户表达组成应用程序的对象以及这些对象之间丰富的相互依赖关系。 -
在容器内部,以BeanDefinition存在,BeanDefinition 包括:
A. clas名称(全限定名称)
B. Bean 行为配置元素,它说明 Bean 在容器中的行为方式(范围、生命周期回调等)
C. 对 bean 执行其工作所需的其他 bean 的引用。这些引用也称为协作者或依赖项。
D. 在新创建的对象中设置的其他配置设置——例如,池的大小限制或在管理连接池的 bean 中使用的连接数 -
ApplicationContext/容器允许在”容器之外“向容器注册Bean,可以通过BeanFactory 实现。
ApplicationContext的BeanFactory,会返回BeanFactory的实现类DefaultListableBeanFactory,它支持以下方法:registerSingleton(…) 和 registerBeanDefinition(…) -
虽然在一定程度上容器支持”覆盖现有元数据和现有单例实例“,但官方并不支持在运行时注册新bean(同时对工厂进行实时访问),这可能会导致并发访问异常、bean容器中的不一致状态等。
-
如果不显示使用id/name对bean进行命名,那么容器将会自动为其生成一个独特的名称。
-
在命名bean时,约定使用标准Java约定作为实例字段名称。也就是说,bean名称以小写字母开头,并从那里开始采用驼峰式大小写。名称示例大概如accountManager、accountService、userDao、loginController等等。但是如果bean名称的第一个和第二个字符都是大写时,第一个大写也会被保留。
-
关于实例化Bean的方式:
- 构造函数
- 使用静态工厂方法
- 使用实例工厂方法
- 关于依赖注入(DI):
- 依赖注入可以基于构造函数,也可以是基于setter的依赖注入。
- Spring官方建议:对于强制性依赖项使用构造函数,对于可选依赖项使用setter方法/配置方法。(可选意味着后续可以重新配置/重新注入)
- Spring团队通常提倡使用构造函数注入,但是不建议过度使用,否则类的责任太沉重。
- 依赖过程解析:
- 创建容器/ApplicationContext ,初始化全部bean
- 对于每个bean而言,它的依赖来自于:属性,构造函数的参数,或者静态工厂方法的参数。依赖会在创建bean的过程中给到bean本身。
- 无论是属性,还是狗在函数参数,它都是需要被设入的一个值/引用(指的是:对容器中另一个bean的引用)。在设值过程中,默认情况下Spring可以将字符串格式的值转换为所有内置类型,比如int、long、string、boolean等
- 关于循环依赖
比如class A使用构造函数注入class B,同时class B也使用构造函数注入class A。那么Spring容器就会检测到这个循环引用,抛出异常:BeanCurrentlyInCreationException
解决方法:使用setter方法注入,而不是构造函数