Contents

什么是Spring Bean?

1.概述

Bean 是 Spring Framework 的一个关键概念。因此,理解这个概念对于掌握框架并以有效的方式使用它至关重要。 不幸的是,**对于 Spring bean 到底是什么这个简单的问题,并没有明确的答案。**一些解释太低了以至于错过了大局,而另一些解释太模糊了。 本教程将尝试阐明该主题,从官方文档中的描述开始。

2. bean定义

这是Spring Framework 文档 中 bean 的定义 : 在 Spring 中,构成应用程序主干并由 Spring IoC 容器管理的对象称为 bean。bean 是由 Spring IoC 容器实例化、组装和管理的对象。

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

3. 控制反转

简单地说,控制 反转 (IoC) 是**一个对象定义其依赖关系而不创建它们的过程。**该对象将构建此类依赖项的工作委托给 IoC 容器。

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

3.1. 领域类

假设我们有一个类声明:

public class Company {
    private Address address;
    public Company(Address address) {
        this.address = address;
    }
    // getter, setter and other properties
}

这个类需要一个 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. 传统方法

通常,我们使用类的构造函数创建对象:

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

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

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

管理如此多的对象简直就是一场噩梦。这就是控制反转来拯救的地方。

对象可以从 IoC 容器中检索其依赖项,而不是自己构建依赖项。我们需要做的就是为容器提供适当的配置元数据。

3.3. Bean配置

首先,让我们用*@Component注释来装饰Company*类:

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

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

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

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

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

3.4. IoC

由于我们在配置类中定义了 bean,我们需要AnnotationConfigApplicationContext类的实例来构建容器

ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);

快速测试验证我们的 bean 的存在和属性值:

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

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