上一篇讲了 Spring Boot 的主程序类
本篇来讲一讲 beans
Spring Boot 初识:
【Spring Boot 初识丨一】入门实战
【Spring Boot 初识丨二】maven
【Spring Boot 初识丨三】starter
【Spring Boot 初识丨四】主应用类
Spring beans是Spring框架中的核心概念之一,它们是Spring IoC容器中的实例对象。在Spring应用程序中,所有的组件都是通过Spring容器进行管理,而Spring容器就是通过创建和管理bean来实现的。
Spring bean可以是一个普通的Java类,也可以是一个接口或抽象类的实现类。当一个Java类被标记为@Component、@Service、@Repository等注解时,它就会成为Spring bean,并被Spring容器管理。
Spring容器会自动创建和管理bean的生命周期,包括实例化、属性注入、依赖注入、初始化和销毁等过程。开发者可以通过配置文件或注解的方式来定义bean的属性和依赖关系,从而实现代码的重用和解耦。
bean元素包含:
每个 bean 都有一个或多个标识符。这些标识符在承载 bean 的容器中必须是唯一的。一个 bean 通常只有一个标识符,但如果需要多个标识符,则多出的可以视为别名。
在基于 XML 的配置元数据中,您使用 id
和/或 name
属性来指定 bean 标识符。该id
属性允许您准确指定一个 ID。通常这些名称是字母数字(‘myBean’、‘fooService’ 等),但也可以是特殊字符。如果要给bean引入其他别名,也可以在属性中指定name
,用逗号(,)、分号(;)或空格分隔。作为历史记录,在 Spring 3.1 之前的版本中, id属性被键入为 xsd:ID,它限制了可能的字符。从 3.1 开始,现在是xsd:string. 请注意,bean id 的唯一性仍然由容器强制执行,但不再由 XML 解析器强制执行。
您不需要为 bean 提供名称或 ID。如果没有显式提供名称或 ID,容器会为该 bean 生成一个唯一的名称。但是,如果您想通过使用ref
元素或Service Locator 查找通过名称引用该 bean,则必须提供一个名称。
bean的命名约定:
约定是在命名 bean 时使用标准 Java 约定作为实例字段名称。也就是说,bean 名称以小写字母开头,并从那时起采用驼峰式大小写。此类名称的示例为’accountManager’, ‘accountService’, ‘userDao’, ‘loginController’ (不带引号) 等
始终如一地命名 bean 使您的配置更易于阅读和理解,并且如果您使用的是 Spring AOP,将通知应用于一组按名称相关的 bean 时会有很大帮助。
在 bean 定义之外为 bean 添加别名:
在基于 XML 的配置元数据中,您可以使用 元素来完成此操作
Spring Bean的生命周期包括以下四个阶段:
bean 定义本质上是创建一个或多个对象的方法。当被请求时,容器查看命名 bean 的方法,并使用该 bean 定义封装的配置元数据来创建(或获取)实际对象。
如果使用基于 XML 的配置元数据,则可以在 元素的 class 属性中指定要实例化的对象的类型(或类) 。该class 属性在内部是BeanDefinition实例上的class属性,通常是必需的。
您可以通过以下两种方式之一使用Class属性:
Spring Bean的创建实例化方法:
内部类名
如果要为 static嵌套类配置 bean 定义,则必须使用 内部类的二进制名称。
请注意在名称中使用$字符将内部类名称与外部类名称分开。
基于构造函数的依赖注入 是通过容器调用带有多个参数的构造函数来实现的,每个参数代表一个依赖项。使用特定参数调用static的工厂方法来构造 bean 几乎是等价的。
基于 Setter 的依赖注入是通过容器在调用无参数构造函数或无参数static工厂方法实例化 bean 后调用 bean 上的 setter 方法来实现的。
依赖解析过程:
容器执行 bean 依赖解析如下:
Spring 容器在创建容器时验证每个 bean 的配置,包括当 bean 引用属性引用有效的bean 时的验证。但是,bean 属性本身在实际创建bean 时才会设置 。单例作用域并设置为预实例化的Bean(默认值)被创建。bean的作用域未定义时,bean 仅在被请求时创建。创建 bean 可能会导致创建 bean 图,因为创建并分配了 bean 的依赖项及其依赖项的依赖项(等等)。
InitializingBean 接口允许 bean 在容器设置了 bean 的所有必要属性后执行初始化工作。
建议不要使用 InitializingBean 接口,因为它会将代码不必要地耦合到 Spring。或者,使用 注释或指定 POJO 初始化方法。对于基于 XML 的配置元数据,您可以使用init-method属性来指定具有void无参数签名的方法的名称。
DisposableBean 接口允许 bean 在包含它的容器被销毁时获得回调。
建议不要使用 DisposableBean回调接口,因为它会将代码不必要地耦合到 Spring。或者,使用 注释或指定 bean 定义支持的通用方法。使用基于 XML 的配置元数据,您可以 使用destroy-method
当您编写不使用 Spring 特定接口 InitializingBean和 DisposableBean回调接口的初始化和销毁方法回调时,通常使用诸如init()、 initialize()、dispose()等的方法。理想情况下,此类生命周期回调方法的名称在整个项目中是标准化的,以便所有开发人员使用相同的方法名称并确保一致性。
您可以配置Spring 容器来查找命名初始化和销毁每个bean上的回调方法名称 。这意味着您作为应用程序开发人员可以编写应用程序类并使用名为init() 的初始化回调,而无需为每个 bean 定义配置init-method="init"属性。Spring IoC 容器在创建 bean 时调用该方法(并根据前面描述的标准生命周期回调契约)。此功能还为初始化和销毁方法回调强制执行一致的命名约定。
顶级元素属性上的default-init-method属性的存在导致 Spring IoC 容器将在 bean 上调用的init方法识别为初始化方法回调。在创建和组装bean 时,如果bean 类有这样的方法,就会在适当的时候调用它。
通过使用顶级元素上的default-destroy-method属性,您可以类似地(在 XML 中)配置销毁方法回调。
如果现有的 bean 类已经具有与约定不同的回调方法,您可以通过使用
当您创建一个 bean 定义时,您创建了一个 方法,用于创建由该 bean 定义定义的类的实际实例。bean 定义是方法的想法很重要,因为这意味着,与类一样,您可以从单个方法创建许多对象实例。
您不仅可以控制要插入到从特定 bean 定义创建的对象中的各种依赖项和配置值,还可以控制从特定 bean 定义创建的对象的范围。这种方法强大而灵活,因为您可以通过配置选择您创建的对象的范围,而不必在 Java 类级别对象的范围。Bean 可以定义为部署在多个作用域的一个:开箱即用,Spring 框架支持五个作用域,其中三个只有在您使用 web-aware ApplicationContext 时才可用。
以下作用域是开箱即用的,也可以创建自定义作用域。
bean 的作用域 | 描述 |
---|---|
singleton | (默认)将单个 bean 定义的范围限定为每个 Spring IoC 容器的单个对象实例。 |
prototype | 将单个 bean 定义的范围限定为任意数量的对象实例。 |
request | 将单个 bean 定义限定为单个 HTTP 请求的生命周期;也就是说,每个 HTTP 请求都有自己的 bean 实例,该实例是在单个 bean 定义的基础上创建的。仅在 web-aware Spring ApplicationContext的上下文中有效 。 |
session | 将单个 bean 定义限定为 HTTP Session的生命周期。仅在 web-aware Spring ApplicationContext 的上下文中有效 |
global session | 将单个 bean 定义限定为全局 HTTP Session 的生命周期。通常仅在 portlet 上下文中使用时才有效。仅在 web-aware Spring ApplicationContext 的上下文中有效 。 |
自定义作用域:
可以定义自己的作用域,甚至重新定义现有的作用域,尽管后者被认为是不好的做法,并且不能 覆盖内置singleton和 prototype的作用域。
如果喜欢的话,欢迎 关注 点赞 评论 收藏 一起讨论 你的评价就是我✍️创作的动力!