What is a Spring Bean? – 什么是Spring Bean?

最后修改: 2018年 9月 28日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Bean is a key concept of the Spring Framework. So understanding this notion is crucial to get the hang of the framework and use it in an effective way.

Bean是Spring框架的一个关键概念。因此,理解这个概念对于掌握该框架并以有效的方式使用它至关重要。

Unfortunately, there aren’t clear answers to the simple question of what a Spring bean really is. Some explanations go to such a low level that the big picture is missed, whereas others are too vague.

不幸的是,对于Spring Bean到底是什么这个简单的问题,并没有明确的答案。有些解释到了很低的层次,以至于错过了大局,而有些解释则过于模糊。

This tutorial will try to shed light on the topic, starting with a description in the official documentation.

本教程将从官方文档中的描述开始,尝试阐明这一主题。

2. Bean Definition

2.Bean的定义

Here’s a definition of beans in the Spring Framework documentation:

下面是Spring框架文档中对bean的定义。

In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container.

在Spring中,构成你的应用程序的骨干并由Spring IoC容器管理的对象被称为Bean。Bean是一个由Spring IoC容器实例化、组装和管理的对象。

This definition is concise and gets to the point but fails to elaborate on an important element: the Spring IoC container. Let’s take a closer look to see what it is and the benefits it brings in.

这个定义简明扼要,切中要害但却没有详细说明一个重要的元素:Spring IoC容器。让我们仔细看看它是什么以及它带来的好处。

3. Inversion of Control

3.控制的颠倒

Simply put, Inversion of Control (IoC) is a process in which an object defines its dependencies without creating them. This object delegates the job of constructing such dependencies to an IoC container.

简单地说,I控制的转换(IoC)是一个过程,其中一个对象定义了其依赖关系,而没有创建它们。这个对象将构建这种依赖关系的工作委托给一个IoC容器。

Let’s start with the declaration of a couple of domain classes before diving into IoC.

在深入研究IoC之前,让我们先从几个领域类的声明开始。

3.1. Domain Classes

3.1.领域类

Assume we have a class declaration:

假设我们有一个类声明。

public class Company {
    private Address address;

    public Company(Address address) {
        this.address = address;
    }

    // getter, setter and other properties
}

This class needs a collaborator of type Address:

这个类需要一个Address类型的合作者。

public class Address {
    private String street;
    private int number;

    public Address(String street, int number) {
        this.street = street;
        this.number = number;
    }

    // getters and setters
}

3.2. Traditional Approach

3.2.传统方法

Normally, we create objects with their classes’ constructors:

通常情况下,我们用类的构造函数来创建对象。

Address address = new Address("High Street", 1000);
Company company = new Company(address);

There’s nothing wrong with this approach, but wouldn’t it be nice to manage the dependencies in a better way?

这种方法没有错,但以更好的方式管理依赖关系不是更好吗?

Imagine an application with dozens or even hundreds of classes. Sometimes we want to share a single instance of a class across the whole application, other times we need a separate object for each use case, and so on.

想象一下,一个有几十个甚至几百个类的应用程序。有时我们想在整个应用程序中共享一个类的单一实例,其他时候我们需要为每个用例提供一个单独的对象,等等。

Managing such a number of objects is nothing short of a nightmare. This is where inversion of control comes to the rescue.

管理如此多的对象简直就是一场噩梦。这就是倒置控制的作用。

Instead of constructing dependencies by itself, an object can retrieve its dependencies from an IoC container. All we need to do is to provide the container with appropriate configuration metadata.

一个对象可以从IoC容器中获取其依赖关系,而不是自己构建依赖关系。我们所要做的就是为容器提供适当的配置元数据。

3.3. Bean Configuration

3.3.Bean配置

First off, let’s decorate the Company class with the @Component annotation:

首先,让我们用@Component注解来装饰Company类。

@Component
public class Company {
    // this body is the same as before
}

Here’s a configuration class supplying bean metadata to an IoC container:

这是一个向IoC容器提供Bean元数据的配置类。

@Configuration
@ComponentScan(basePackageClasses = Company.class)
public class Config {
    @Bean
    public Address getAddress() {
        return new Address("High Street", 1000);
    }
}

The configuration class produces a bean of type Address. It also carries the @ComponentScan annotation, which instructs the container to look for beans in the package containing the Company class.

该配置类产生一个 Address 类型的 bean。它还带有 @ComponentScan 注解,该注解指示容器在包含 Company 类的包中寻找 bean。

When a Spring IoC container constructs objects of those types, all the objects are called Spring beans, as they are managed by the IoC container.

当Spring IoC容器构建这些类型的对象时,所有对象都被称为Spring Bean,因为它们由IoC容器管理。

3.4. IoC in Action

3.4.行动中的IoC

Since we defined beans in a configuration class, we’ll need an instance of the AnnotationConfigApplicationContext class to build up a container:

由于我们在一个配置类中定义了Bean,我们需要一个AnnotationConfigApplicationContext类的实例来建立一个容器

ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);

A quick test verifies the existence and the property values of our beans:

一个快速测试验证了我们的Bean的存在和属性值。

Company company = context.getBean("company", Company.class);
assertEquals("High Street", company.getAddress().getStreet());
assertEquals(1000, company.getAddress().getNumber());

The result proves that the IoC container has created and initialized beans correctly.

结果证明,IoC容器已经正确地创建和初始化了Bean。

4. Conclusion

4.结论

This article gave a brief description of Spring beans and their relationship with an IoC container.

这篇文章对Spring Bean及其与IoC容器的关系进行了简要描述。

The complete source code can be found over on GitHub.

完整的源代码可以在GitHub上找到over