BeanDefinition
是 Spring Framework 中一个核心的接口,它描述了一个 Bean 的定义。你可以把它看作是 Spring IoC 容器中 Bean 的“蓝图”或“配置元数据”。它包含了 Spring 容器创建、配置和管理 Bean 所需的所有信息。
BeanDefinition
中包含的信息:
-
Bean 的类名 (Class Name): Bean 的全限定类名(例如,
com.example.MyService
)。 -
Bean 的作用域 (Scope): 指定 Bean 的生命周期和可见性。常见的作用域有:
singleton
(默认): 在 Spring 容器中只有一个 Bean 实例。prototype
: 每次请求 Bean 时都会创建一个新的实例。request
: 在 Web 应用中,每个 HTTP 请求都有一个 Bean 实例。session
: 在 Web 应用中,每个 HTTP 会话有一个 Bean 实例。application
: 在 Web 应用中,每个ServletContext
有一个 Bean 实例。globalSession
: 在 Portlet 应用中,每个全局会话有一个 Bean 实例。- 自定义作用域
-
Bean 的构造函数参数 (Constructor Arguments): 用于构造函数注入的参数值。
- 可以通过索引或类型指定参数。
- 可以是字面量值、对其他 Bean 的引用、集合等。
-
Bean 的属性值 (Property Values): 用于 Setter 方法注入的属性值。
- 可以是字面量值、对其他 Bean 的引用、集合等。
-
Bean 的依赖关系 (Dependencies): 该 Bean 所依赖的其他 Bean(通过
depends-on
属性或自动装配指定)。 -
Bean 的初始化方法 (Init Method): 在 Bean 实例化和属性设置完成后调用的方法。
- 可以通过
@PostConstruct
注解指定。 - 可以通过实现
InitializingBean
接口的afterPropertiesSet
方法指定。 - 可以在 XML 配置中使用
init-method
属性指定。
- 可以通过
-
Bean 的销毁方法 (Destroy Method): 在 Bean 被销毁之前调用的方法。
- 可以通过
@PreDestroy
注解指定。 - 可以通过实现
DisposableBean
接口的destroy
方法指定。 - 可以在 XML 配置中使用
destroy-method
属性指定。
- 可以通过
-
Bean 是否是懒加载 (Lazy Initialization): 是否在容器启动时立即创建 Bean,还是在第一次请求时才创建(默认为
false
,即立即创建)。 -
Bean 的自动装配模式 (Autowiring Mode): 如何自动解析和注入 Bean 的依赖关系。
no
(默认): 不自动装配。byName
: 根据 Bean 的名称自动装配。byType
: 根据 Bean 的类型自动装配。constructor
: 类似于byType
,但应用于构造函数参数。autodetect
: 已过时, Spring 3.0 之前使用.
-
Bean 的名称 (Bean Name/ID): 用于在容器中唯一标识 Bean。
- 如果没有指定名称,Spring 会自动生成一个唯一的名称。
-
Bean 的别名 (Aliases): 其他可以用来引用该 Bean 的名称。
-
是否是抽象 Bean (Abstract): 抽象 Bean 不能被实例化,通常用作模板。
-
是否是单例 (Singleton): 指示 Bean 是否是单例(
true
或false
,与scope
属性可能重复)。 -
是否是原型 (Prototype): 指示 Bean 是否是原型。
-
是否是主要候选者 (Primary): 当多个 Bean 满足自动装配条件时,优先选择主要候选者。
-
FactoryBean Name: 如果 Bean 是一个
FactoryBean
,可以使用&
+ Bean 名称来引用FactoryBean
本身,而不是它创建的对象。 -
其他元数据: 例如,Bean 的描述信息、角色提示(
ROLE_APPLICATION
、ROLE_SUPPORT
、ROLE_INFRASTRUCTURE
)、方法覆盖(MethodOverrides)等。
BeanDefinition
的主要实现类:
RootBeanDefinition
: 根 Bean 定义,通常用于定义普通的 Bean。ChildBeanDefinition
: 子 Bean 定义,继承自父 Bean 定义,可以覆盖或添加一些属性。GenericBeanDefinition
: 通用的 Bean 定义,可以独立使用,也可以作为父 Bean 定义。ScannedGenericBeanDefinition
:GenericBeanDefinition
的子类,用于通过类路径扫描(@Component
、@Service
等)生成的 Bean 定义。AnnotatedBeanDefinition
: 带有注解信息的 Bean 定义的接口。AnnotatedGenericBeanDefinition
: 通用的带有注解信息的 Bean 定义.ConfigurationClassBeanDefinition
: 表示由@Configuration
类中的@Bean
方法定义的 Bean。
BeanDefinition
的作用:
- 存储 Bean 的元数据:
BeanDefinition
对象保存了创建和配置 Bean 所需的所有信息。 - 作为 Bean 的模板: Spring 容器根据
BeanDefinition
来创建 Bean 的实例。 - 支持 Bean 的继承: 子 Bean 定义可以继承父 Bean 定义,减少配置的重复。
- 支持 Bean 的修改:
BeanFactoryPostProcessor
可以在 Bean 实例化之前修改BeanDefinition
。
获取 BeanDefinition
:
可以通过 BeanFactory
或 BeanDefinitionRegistry
的以下方法获取 BeanDefinition
:
BeanFactory.getBeanDefinition(String beanName)
BeanDefinitionRegistry.getBeanDefinition(String beanName)
BeanDefinitionRegistry.getBeanDefinitionNames()
(获取所有 Bean 定义的名称)BeanDefinitionRegistry.containsBeanDefinition(String beanName)
示例 (编程式创建 BeanDefinition
):
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
public class BeanDefinitionExample {
public static void main(String[] args) {
// 创建 RootBeanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(MyService.class); // 设置 Bean 的类
beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON); // 设置作用域
beanDefinition.setLazyInit(false); // 设置是否懒加载
beanDefinition.setInitMethodName("init"); // 设置初始化方法
beanDefinition.setDestroyMethodName("cleanup"); // 设置销毁方法
// ... 设置其他属性 ...
// 可以将 beanDefinition 注册到 BeanDefinitionRegistry (例如 DefaultListableBeanFactory)
// ...
}
static class MyService {
public void init() {
System.out.println("MyService initialized");
}
public void cleanup() {
System.out.println("MyService destroyed");
}
}
}
总结:
BeanDefinition
是 Spring 中描述 Bean 的核心接口。它包含了创建、配置和管理 Bean 所需的所有元数据。 Spring 容器根据 BeanDefinition
来创建 Bean 的实例,并管理它们的生命周期。