BeanDefinition
BeanDefinition 是用来描述创建 Bean 的信息,包括 Bean 的 class ,属性填充,是否懒加载等信息。
BeanDefinition 跟 Bean 的关系,就好像是类与对象的关系,Bean 的创建依赖 BeanDefinition。
BeanDefinition 的源码如下:
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
// singleton 类型 Bean 的标志
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
// prototype 类型 Bean 的标志
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
// BeanDefinition 的角色信息,表示是通过用户创建的 bean
int ROLE_APPLICATION = 0;
// BeanDefinition 的角色信息,表示该 Bean 用于支撑某些配置信息
int ROLE_SUPPORT = 1;
// BeanDefinition 的角色信息,表示该 bean 用于支撑一些 Spring 内部运作
int ROLE_INFRASTRUCTURE = 2;
/**
* bean 的 parentName 的 setter 和 getter 方法
* parentName 表示 Bean 的父级名字
*/
void setParentName(@Nullable String parentName);
String getParentName();
// BeanClassName 的 setter 跟 getter 方法
void setBeanClassName(@Nullable String beanClassName);
String getBeanClassName();
/**
* scope 的 setter 跟 getter 方法
* scope 表示这个 Bean 的类型,是 singleton 还是 prototype 类型
*/
void setScope(@Nullable String scope);
String getScope();
/**
* lazyInit 的 setter 跟 getter 方法
* lazyInit 表示是否懒加载 Bean
*/
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
// dependsOn 的 setter 跟 getter 方法
void setDependsOn(@Nullable String... dependsOn);
String[] getDependsOn();
// autowireCandidate 的 setter 跟 getter 方法
void setAutowireCandidate(boolean autowireCandidate);
boolean isAutowireCandidate();
// primary 的 setter 跟 getter 方法
void setPrimary(boolean primary);
boolean isPrimary();
// fatoryBeanName 的 setter 跟 getter 方法
void setFactoryBeanName(@Nullable String factoryBeanName);
String getFactoryBeanName();
// factoryMethodName 的 setter 跟 getter 方法
void setFactoryMethodName(@Nullable String factoryMethodName);
String getFactoryMethodName();
// 获取 ConstructorArgumentValues 的值
ConstructorArgumentValues getConstructorArgumentValues();
// 判断是否有 ConstructorArgumentValues
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
// 获取 PropertyValues
MutablePropertyValues getPropertyValues();
// 判断 PropertyValues 是否为空
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
// initMthodName 的 getter 跟 setter 方法
void setInitMethodName(@Nullable String initMethodName);
String getInitMethodName();
// destroyMethodName 的 getter 跟 setter 方法
void setDestroyMethodName(@Nullable String destroyMethodName);
String getDestroyMethodName();
// bean 角色的 setter 跟 getter 方法
void setRole(int role);
int getRole();
/**
* description 的 getter 和 setter 方法
* description 表示 bean 的描述信息
*/
void setDescription(@Nullable String description);
String getDescription();
// 返回 Bean 的 ResolvableType
ResolvableType getResolvableType();
// 是否为 singleton 类型的 bean
boolean isSingleton();
// 是否为 prototype 类型的 bean
boolean isPrototype();
// 是否为抽象类,如果是则表示这个 bean 无法初始化
boolean isAbstract();
// 获取资源描述信息
String getResourceDescription();
// 获取被包装的 BeanDefinition,如果这个 BeanDefinition 是包装类,那么就会返回被包装的原始类
BeanDefinition getOriginatingBeanDefinition();
}
BeanDefinition 的常用子类
- AbstractBeanDefinition
- RootBeanDefinition
- ChildBeanDefinition
- GenericBeanDefinition
- AnnotatedGenericBeanDefinition
AbstractBeanDefinition
BeanDefinition 的抽象实现类,对于 BeanDefinition 的大部分接口提供了关联的字段。
RootBeanDefinition
AbstractBeanDefinition 的实现类之一,是常用的 BeanDefinition
用法
public static class User {
protected String username;
protected String address;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", address='" + address + '\'' +
'}';
}
}
@Test
void rbdTest() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
MutablePropertyValues mpv = new MutablePropertyValues();
mpv.add("username", "yosoro");
mpv.add("address", "cn");
RootBeanDefinition rbd = new RootBeanDefinition(User.class, null, mpv);
ctx.registerBeanDefinition("user", rbd);
}
输出结果
User{username='yosoro', address='cn'}
ChildBeanDefinition
AbstractBeanDefinition 的实现类之一,它提供了继承父 BeanDefinition 的能力,使得子 BeanDefinition 也能拥有父 BeanDefinition 的能力
用法
public static class Person extends User {
private String nickName;
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
@Override
public String toString() {
return "Person{" +
"nickName='" + nickName + '\'' +
", username='" + username + '\'' +
", address='" + address + '\'' +
'}';
}
}
public static class User {
protected String username;
protected String address;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", address='" + address + '\'' +
'}';
}
}
@Test
void rbdTest() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
MutablePropertyValues mpv = new MutablePropertyValues();
mpv.add("username", "yosoro");
mpv.add("address", "cn");
RootBeanDefinition rbd = new RootBeanDefinition(User.class, null, mpv);
ctx.registerBeanDefinition("user", rbd);
ChildBeanDefinition cbd = new ChildBeanDefinition("user");
cbd.setBeanClass(Person.class);
cbd.getPropertyValues().add("nickName", "wata");
ctx.registerBeanDefinition("person", cbd);
ctx.refresh();
System.out.println(ctx.getBean("person", Person.class));
}
输出结果
Person{nickName='wata', username='yosoro', address='cn'}
GenericBeanDefinition
AbstractBeanDefinition 的实现类之一,同时涵盖了 RootBeanDefinition 和 ChildBeanDefinition 的能力
用法
User 跟 Person 类与 ChildBeanDefinition 一样,不一样的是 rbtTest() 的代码
@Test
void rbdTest() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
MutablePropertyValues mpv = new MutablePropertyValues();
mpv.add("username", "yosoro");
mpv.add("address", "cn");
RootBeanDefinition rbd = new RootBeanDefinition(User.class, null, mpv);
ctx.registerBeanDefinition("user", rbd);
GenericBeanDefinition cbd = new GenericBeanDefinition(rbd);
cbd.setBeanClass(Person.class);
cbd.getPropertyValues().add("nickName", "wata");
ctx.registerBeanDefinition("person", cbd);
ctx.refresh();
System.out.println(ctx.getBean("person", Person.class));
}
输出结果
Person{nickName='wata', username='yosoro', address='cn'}
AnnotatedGenericBeanDefinition
表示该 Bean 是包含 @Component 的注解,所有通过 @Component 相关的注解创建的 Bean 的 BeanDefinition,都是 AnnotatedGenericBeanDefinition 类型。
用法
// @Configuration 注解包含了 @Component 注解
@Configuration("testConfig")
public static class TestConfig {
@Bean
User testUser() {
return new User();
}
}
@Test
void configBeanTest() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(TestConfig.class);
// AnnotatedGenericBeanDefinition 类型
BeanDefinition testConfigBeanDefinition = ctx.getBeanDefinition("testConfig");
System.out.println(testConfigBeanDefinition.getClass());
// ConfigurationClassBeanDefinitionReader$ConfigurationClassBeanDefinition 类型
BeanDefinition testUserBeanDefinition = ctx.getBeanDefinition("testUser");
System.out.println(testUserBeanDefinition.getClass());
}
输出结果
class org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition
class org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader$ConfigurationClassBeanDefinition
BeanFactoryPostProcessor
BeanFactoryPostProcessor 是在 beanFactory 创建 Bean 之前调用的,我们可以通过 BeanFactoryPostProcessor ,来修改 BeanDefinition 的属性值,以达到修改 Bean 的属性;
BeanFactoryPostProcessor 源码
public interface BeanFactoryPostProcessor {
/*
* Spring 在所有 BeanDefinition 加载完毕后,Bean 创建前调用
* 可以通过该方法来修改 Bena 的属性值
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
使用例子
// 自定义的 BeanFactoryPostProcessor
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String beanName = "testBean";
if(beanFactory.containsBeanDefinition(beanName)){
BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
bd.getPropertyValues().add("field","after change");
}
}
}
// 用到的 BeanClass
public class TestBean implements InitializingBean {
protected Object field;
public TestBean() {
System.out.println("create TestBean");
}
public Object getField() {
return field;
}
public void setField(Object field) {
System.out.println("set field property");
this.field = field;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("invoke afterPropertiesSet method");
}
@Override
public String toString() {
return "TestBean{" +
"field=" + field +
'}';
}
}
// 测试代码
@SpringBootTest
public class CustomBeanFactoryPostProcessorTest {
@Autowired
private ApplicationContext ctx;
@Test
public void test(){
TestBean testBean = ctx.getBean(TestBean.class,"testBean");
System.out.println(testBean);
}
@Configuration
static class Config{
@Bean("testBean")
public TestBean testBean(){
TestBean testBean = new TestBean();
testBean.setField("field value");
return testBean;
}
@Bean
public CustomBeanFactoryPostProcessor customBeanFactoryPostProcessor(){
return new CustomBeanFactoryPostProcessor();
}
}
}
输出结果
TestBean{field=after change}
BeanDefinitionRegistryPostProcessor
BeanFactoryPostProcessor 的子类,可以用于手动添加 BeanDefinition ,以达到添加 Bean 的效果。
BeanDefinitionRegistryPostProcessor 源码
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
* Spring 在调用该方法前,所有 BeanDefinition 已经加载完毕,Bean 创建前调用
* 可以通过该方法来添加 Bean
* 此外,Spring 先执行该方法,然后再执行 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
使用例子
// 自定义的 BeanDefinitionRegistryPostProcessor
public class CustomBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("invoke postProcessBeanFactory method");
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
RootBeanDefinition rbd = new RootBeanDefinition();
rbd.setBeanClass(TestBean.class);
rbd.getPropertyValues().add("field","test");
registry.registerBeanDefinition("testBean",rbd);
System.out.println("add TestBean finish");
}
}
// 这里用到的 TestBean 类跟 BeanFactoryPostProcessor 的例子一样,故不贴
// 测试代码
@SpringBootTest
public class CustomBeanDefinitionRegistryPostProcessorTest {
@Autowired
private ApplicationContext ctx;
@Test
void test(){
final TestBean bean = ctx.getBean(TestBean.class);
System.out.println(bean);
}
@Configuration
static class TestConfig{
@Bean
public CustomBeanDefinitionRegistryPostProcessor customBeanFactoryPostProcessor(){
return new CustomBeanDefinitionRegistryPostProcessor();
}
}
}
输出结果:
add TestBean finish
invoke postProcessBeanFactory method
create TestBean
set field property
invoke afterPropertiesSet method
TestBean{field=test}