是spring定义bean配置元信息的接口,你的bean在被容器托管之前会先被解析成beanDefinition。包含如下部分内容:
说明 |
全类名,具体类 |
bean的名称 或ID、父类名字 |
作用域 |
构造器参数 用于依赖注入 |
属性设置 用于依赖注入 对于pojo的字段 |
自动绑定模式 |
是否延迟加载 |
初始化方法、销毁方法 |
bean的依赖关系、是否为primary Bean |
其实以上内容就是咱们在使用bean过程中都会遇到的东西,只是说框架把这些东西抽象为beanDefinition了。
beanDefinition 怎么构建呢?
- 通过BeanDefinitionBuilder
- AbstractBeanDefinition以及其子类。
// 1.通过 BeanDefinitionBuilder 构建
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
// 通过属性设置
beanDefinitionBuilder
.addPropertyValue("id", 1)
.addPropertyValue("name", "小马哥");
// 获取 BeanDefinition 实例
BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
// BeanDefinition 并非 Bean 终态,可以自定义修改
// 2. 通过 AbstractBeanDefinition 以及派生类
GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
// 设置 Bean 类型
genericBeanDefinition.setBeanClass(User.class);
// 通过 MutablePropertyValues 批量操作属性
MutablePropertyValues propertyValues = new MutablePropertyValues();
// propertyValues.addPropertyValue("id", 1);
// propertyValues.addPropertyValue("name", "小马哥");
propertyValues
.add("id", 1)
.add("name", "小马哥");
// 通过 set MutablePropertyValues 批量操作属性
genericBeanDefinition.setPropertyValues(propertyValues);
将beanDefinition注入容器的方法
通过api方式:
BeanDefinitionRegistry 接口,BeanDefinitionRegistry.registerBeanDefinition()接口方式可以注册。DefaultListableBeanFactory实现类BeanDefinitionRegistry接口,注册实际上是往DefaultListableBeanFactory的一个beanDefinitionMap。
spring还提供了一个接口可以扩展注册beanDefinition。很多三方组件也是实现该类来生成并注册成beanDefinition。
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean definition registry after its
* standard initialization. All regular bean definitions will have been loaded,
* but no beans will have been instantiated yet. This allows for adding further
* bean definitions before the next post-processing phase kicks in.
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
public static void registerUserBeanDefinition(BeanDefinitionRegistry registry, String beanName) {
BeanDefinitionBuilder beanDefinitionBuilder = genericBeanDefinition(User.class);
beanDefinitionBuilder
.addPropertyValue("id", 1L)
.addPropertyValue("name", "小马哥");
// 判断如果 beanName 参数存在时
if (StringUtils.hasText(beanName)) {
// 注册 BeanDefinition
registry.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
} else {
// 非命名 Bean 注册方法
BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinitionBuilder.getBeanDefinition(), registry);
}
}