1、简介
Bean 是 Spring Framework 的核心概念。因此,理解这一概念对于掌握框架并行之有效地使用它显得至关重要。
不幸的是,关于这么简单地问题却没有正确的答案——Spring Bean 到底是什么。有些解释十分低级会使我们囿限于细节之中,而有些却非常模棱两可。
这篇文章将尝试从官方文档中的描述开始阐明 Spring Bean 到底是什么。
2、Bean 的定义
这是官方文档中关于 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 IoC Container。
3、控制反转
简而言之,Inversion of Control 或简称 IoC 是一个对象不用 new 创建它就能定义其依赖关系的过程。对象将创建依赖关系的任务交给了 IoC 容器。
3.1、Domain 类
假设我们声明一个类:
public class Company {
private Address address;
public Company(Address address) {
this.address = address;
}
// getter, setter and other properties
}
Company 类还需要一个 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 来拯救我们的时候。
对象可以从 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 已经被正确初始化了。
4、总结
这篇文章简要介绍了 Spring Bean 以及其与 IoC 容器的关系。
完整源码可以在 Github 上查看。