世界上的Spring Bean是什么?

523

我还没有找到一个我能理解的Spring Bean的高级定义。我经常在Grails文档和书籍中看到它们的引用,但我认为了解它们将是有益的。那么Spring Bean是什么?它们如何使用?它们是否与依赖注入有关?


2
Grails建立在Spring之上。如果你不熟悉Spring,我建议你至少阅读一些相关材料,以便理解你正在使用的技术。 - Jeff Storey
43
我认为这里的评论和Grails文档和书籍中的参考资料一样存在问题:只有那些已经知道它们意思的人才觉得容易理解。对于初学者来说,我发现维基百科的文章描述得更好。 - Elias Dorneles
12
古老版本的Spring之所以在Google上排名靠前,其中一个原因是因为人们不断地从诸如SO等地方链接到它......现在开始看来,http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html可能是更好的起点。 - Ian Roberts
5
+1 @IanRoberts。这里是当前版本的链接 - dmahapatro
1
他们说IoC也被称为DI,但这并没有帮助理解IoC。虽然它们是相关的,但IoC更加广泛。 - Aluan Haddad
我喜欢这篇关于Spring Bean的描述:https://www.baeldung.com/spring-bean - masterxilo
17个回答

253

Spring核心技术参考文档描述了什么是bean。

根据Spring IoC容器和Bean简介部分(其中"IoC"表示"控制反转"):

在Spring中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。 Bean是由Spring IoC容器实例化、组装和管理的对象。否则,bean只是应用程序中众多对象之一。bean及其之间的依赖关系反映在容器使用的配置元数据中。

Bean和作用域在Bean作用域部分中进行了描述:

当您创建一个bean定义时,实际上是在创建一个类的实例的配方。将bean定义视为配方的想法非常重要,因为这意味着,与类一样,您可以从单个配方创建多个对象实例。您不仅可以控制要插入到从特定bean定义创建的对象中的各种依赖项和配置值,而且还可以控制从特定bean定义创建的对象的范围。这种方法非常强大和灵活,因为您可以通过配置选择要创建的对象的范围,而不必在Java类级别上烘焙对象的范围。 Bean可以定义为部署在多个范围之一。

14
这些是由容器管理的对象,我不需要亲自操作,但如果我想获取某个bean并调用一些方法或检索属性,则可以向Spring“请求”该bean吗? - grantmcconnaughey
3
是的,你想通过容器来处理对象,包括它们的创建、检索等。 - Juned Ahsan
29
@grantmc 这有点类似,但是控制反转的概念应该理解为与“请求”相反:你不再“请求”需要的东西,而是“声明”你将需要它。当你启动应用程序时,框架会检查所有声明并设置适当的实例。 - Elias Dorneles
8
我怎样声明我需要它呢?是在使用@Autowired时吗?还是仅仅在进行import时就可以了? - Mikhail Batcer
22
定义IoC对于Spring的新手来说会很有帮助,但不要改变原意。 - Lucas
8
@lucas 同意。IoC是“控制反转”。请参阅优秀的问答:什么是Spring框架中的依赖注入和控制反转?什么是控制反转? - mhradek

180

Spring beans是由Spring容器管理的实例对象,也就是说,它们是由框架创建和连接的,并放入一个“对象池”(容器)中,您以后可以从中获取它们。

"连接"部分是依赖注入的全部内容,这意味着您只需说“我需要这个东西”,框架就会遵循某些规则为您获取适当的实例。

对于不习惯使用 Spring 的人,我认为维基百科的 Spring 框架文章有一个不错的描述

  

Spring 框架的核心是反转控制容器,它使用反射提供了一种一致的方式来配置和管理 Java 对象。容器负责管理特定对象的生命周期:创建这些对象、调用它们的初始化方法并通过互相连接它们配置这些对象。

     

容器创建的对象也被称为托管对象或 bean。容器可以通过加载 XML 文件或检测配置类上的特定 Java 注解进行配置。这些数据源包含 bean 定义,这些定义提供了创建 bean 所需的信息。

     

对象可以通过依赖查找或依赖注入来获取。依赖查找是一种模式,调用者要求容器对象返回具有特定名称或特定类型的对象。依赖注入是一种模式,容器通过名称将对象传递给其他对象,可以通过构造函数、属性或工厂方法进行传递。


实例仅仅是对象的另一个说法。当你使用“对象实例”时,难道不是在说对象对象吗? - Flame of udun
有趣的问题。根据维基百科,我应该说“实例对象”:https://en.wikipedia.org/wiki/Instance_(computer_science) - Elias Dorneles
3
兔子洞越深。 - Flame of udun
今天我意识到“对象对象”(因此也包括对象实例)对我来说实际上是有意义的,因为我习惯于使用类也是一个对象的语言(因此你有类对象和“对象”对象)。 无论如何,我已根据维基百科文章更新了描述,使用“实例对象”。^^ - Elias Dorneles
所以,Spring Bean 是一个类还是一个类的实例? - Reacher
1
@Ruizhi 一个常规对象,即类的实例--这个讨论是关于使用正确的表达来引用对象的一个离题。 :) - Elias Dorneles

110

首先让我们了解Spring:

Spring是一个轻量级和灵活的框架。

类比:
enter image description here

Java Beans 是将许多对象封装到一个单一对象(bean)中的类。名称“Bean”指代旨在为Java创建可重用软件组件的标准。

Spring Bean:是在Spring Container中创建、管理和销毁的对象。我们可以通过元数据(xml或注释)将对象注入Spring容器中,这被称为控制反转。

类比: 假设农民拥有一个种植着种子(或豆子)的农田。 在这里,农民就是Spring Framework,农田是Spring容器,豆子是Spring Bean,种植是Spring处理器。

enter image description here

像bean生命周期一样,Spring Bean也有自己的生命周期。

enter image description here

enter image description here

图片来源

Spring 中 bean 的生命周期顺序如下:

  • 实例化:首先,Spring 容器从 XML 文件中查找 bean 的定义并对其进行实例化。

  • 填充属性:使用依赖注入,Spring 会按照 bean 定义中指定的方式填充所有属性。

  • 设置 Bean 名称:如果 bean 实现了 BeanNameAware 接口,Spring 将 bean 的 ID 传递给 setBeanName() 方法。

  • 设置 Bean 工厂:如果 bean 实现了 BeanFactoryAware 接口,Spring 会将 beanfactory 传递给 setBeanFactory() 方法。

  • 前置初始化:也称为 bean 的后处理。如果与 bean 相关联的有任何 BeanPostProcessors, Spring 将调用它们的 postProcesserBeforeInitialization() 方法。

  • 初始化 Bean:如果 bean 实现了 IntializingBean 接口,则 Spring 会调用其 afterPropertySet() 方法。如果 bean 声明了 init 方法,则调用指定的初始化方法。

  • 后置初始化:如果与 bean 相关联的有任何 BeanPostProcessors,Spring 将调用它们的 postProcessAfterInitialization() 方法。

  • 准备就绪:现在该 bean 已经可以被应用程序使用了。

  • 销毁:如果 bean 实现了 DisposableBean 接口,则会调用其 destroy() 方法。


18
抱歉,但说“Spring是一个轻量级的[...]框架。”实在是太荒谬了。 - avf
1
@avf 嗯,我不是专家,但我已经听很多次Spring是一个轻量级框架,并且在许多地方阅读过它是轻量级的。但就像我说的,我并没有太多的知识。你能分享一些信息吗,告诉我你怎么知道它不是轻量级的?这样我就能知道它是否轻量级了。谢谢。 - LosmiNCL
1
@LosmiNCL 相对于之前的版本,它的重量更轻。早在2004年的Spring文档1.1.1版本中就已经提到: "Spring提供了一个轻量级的解决方案,用于构建企业级应用程序..." 这里有一个StackOverflow的答案,解释了相对较重的问题:https://stackoverflow.com/a/8117252/249411 - undefined

24

你部分地理解了它。根据你的需求定制豆子,然后使用一种被普遍称为IoC(Inversion of Control)的方法告诉Spring容器在需要时管理它,这个术语最初由Martin Fowler创造,并且也被称为依赖注入(DI)。

您以一种方式连接这些豆子,以便不必关心实例化或评估对豆子的任何依赖关系。这通常被称为好莱坞原则

谷歌是探索更多相关内容的最佳工具,除此之外,在这个问题中您将会受到大量链接的回应。 :)


7
需要翻译的内容:Cannot not point out that IoC is the concept, and DI is (one of) the technique which can be used to achieve IoC, they are not replaceable definitions.我必须指出IoC是一个概念,而DI是实现IoC的技术之一,它们不是可以互换的定义。 - kekko12

24

一个Bean是一个POJO(Plain Old Java Object),由Spring容器管理。

默认情况下,Spring容器仅创建一个bean实例。该bean被缓存在内存中,因此所有对bean的请求将返回对同一bean的共享引用。

@Bean注释返回一个对象,Spring在应用程序上下文中注册该对象作为bean。方法内部的逻辑负责创建实例。

什么时候使用@Bean注释?

当自动配置不可行时。 例如,当我们想要连接来自第三方库的组件时,因为源代码不可用,所以无法使用@Component注释类。

一个真实的场景可能是有人想要连接到Amazon S3存储桶。 因为源不可用,他必须创建一个@bean。

@Bean
public AmazonS3 awsS3Client() {
    BasicAWSCredentials awsCreds = new BasicAWSCredentials(awsKeyId, accessKey);
    return AmazonS3ClientBuilder.standard().withRegion(Regions.fromName(region))
            .withCredentials(new AWSStaticCredentialsProvider(awsCreds)).build();
}

上述代码的来源 -> https://www.devglan.com/spring-mvc/aws-s3-java

因为我在上面提到了@Component注释。

@Component表示一个被注释的类是一个"组件"。当使用基于注释的配置和类路径扫描时,这些类被认为是自动检测的候选对象。

Component注释将该类注册为单个bean。


14

Spring beans是类。不需要使用new实例化一个类,而是从应用程序上下文中获取一个实例作为bean并将其强制转换为您的类类型,其中bean就是您在应用程序上下文配置中配置的内容。这样,整个应用程序在应用程序期间都会维护单例范围的实例。所有bean都在应用程序上下文被实例化之后按照它们的配置顺序进行初始化。即使您的应用程序中没有任何bean,所有bean实例也已经在创建应用程序上下文之后立即创建。


4
豆子不是类(classes),而是作为类的实例(instances)的对象,由容器实现进行管理。 - Buğra Ekuklu
1
这让我更好地理解了Bean。基本上,它是在不使用著名的“new”关键字的情况下实例化一个类。谢谢。 - Delice

12
  • Spring beans是由Spring IOC容器管理的对象实例。

  • Spring IOC容器负责Bean的创建、维护和删除。

  • 我们可以通过Wiring和Auto Wiring将bean放入Spring中。

  • Wiring指的是手动将其配置到XML文件中。

  • Auto Wiring指的是在Java文件中放置注解,然后Spring自动扫描根上下文中的Java配置文件,创建它并将其放入Spring的容器中。


11

Spring拥有IoC容器,它承载了Bean的袋子;创建、维护和删除都是Spring容器的职责。我们可以通过Wiring和Auto Wiring将Bean放入Spring中。Wiring意味着我们手动将其配置到XML文件中,而"Auto Wiring"意味着我们将注释放在Java文件中,然后Spring会自动扫描根目录下的Java配置文件,并将其制作并放入Spring的袋子中。

这里是详细的URI链接,您可以获得更多有关Beans的信息


10

在Spring Boot应用程序中,“bean”只是Spring框架在应用程序启动时创建的Java对象。

这个对象的目的可能是任何东西 - 配置、服务、数据库连接工厂等 - Spring并不在意。

大多数bean依赖于其他bean,例如实体管理器可能需要数据库连接。Spring框架能够自动地找出如何将这些bean连接在一起。从您作为应用程序开发人员的角度来看,您只需声明所需的bean,它们就会“神奇地”出现在您的应用程序中,准备好使用。


2

在Spring中,那些构成应用程序主干并由Spring IoC容器管理的对象被称为bean。一个bean只是由Spring IoC容器实例化、组装和管理的一个对象;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接