2021-07-11阅读小笔记:Spring ioc 之 BeanDefinition与BeanDefinitionRegistry

1、什么是 BeanDefinitionRegistry ?

BeanDefinitionRegistry 可以根据字面意思去理解,它就是 BeanDefinition 的注册中心,负责管理IOC容器中的所有bean的定义信息;同时,它支撑其他组件实现动态注册Bean,如 ImportBeanDefinitionRegistrar,我们可实现 ImportBeanDefinitionRegistrar 接口,根据定制化需求往 BeanDefinitionRegistry 里面注册 Bean 信息,然后利用 @Import 注入从而定制化我们需要的Bean实例。

BeanDefinitionRegistry 的落地实现是 DefaultListableBeanFactory。

2、BeanDefinitionRegistry 的作用是什么?它的最终形态是什么?

BeanDefinitionRegistry 的作用是维护 BeanDefinition 的使用,它支持对 BeanDefinition 进行注册、修改和删除。

它的最终形态也就是上面提到的落地实现 DefaultListableBeanFactory。在 DefaultListableBeanFactory 的实现中,利用的是 JDK 自带的支持并发安全的 ConcurrentHashMap。详细看下面代码:

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    
    // .......
    private final Map<String, BeanDefinition> beanDefinitionMap;
    
    public DefaultListableBeanFactory() {
        
        // ....
        this.beanDefinitionMap = new ConcurrentHashMap(256);
        // ....
    }
    // .......
}

3、BeanDefinition 与 BeanDefinitionRegistry 的关系是什么?

上面也提到了,BeanDefinitionRegistry 是 BeanDefinition 的注册中心,管理了IOC容器中的所有 Bean 的定义信息,支持对 BeanDefinition 进行注册、修改和删除操作。

4、动手实现借助 BeanDefinitionRegistry 注册移除 BeanDefinition。

4.1 添加-ImportBeanDefinitionRegistrar

实体类:

@Data
public class Person {
    private String name;
}

@Data
public class Cat {
    private Person person;
}

自定义ImportBeanDefinitionRegistrar,用于注册BeanDefinition:

public class CatImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        registry.registerBeanDefinition("myPerson",new RootBeanDefinition(Person.class));
        registry.registerBeanDefinition("myCat", BeanDefinitionBuilder.genericBeanDefinition(Cat.class).addPropertyReference("person","myPerson").getBeanDefinition());
    }
}

Java配置类,导入上面的组件:

@Configuration
@Import(CatImportBeanDefinitionRegistrar.class)
public class BeanConfiguration {
}

运行应用:

public class Application {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfiguration.class);
        String[] beanNames = applicationContext.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            System.out.println(beanName);
            if (beanName.contains("Cat")){
                Cat cat = (Cat) applicationContext.getBean(beanName);
                System.out.println(cat);
            }
            if (beanName.contains("Person")){
                Person person = (Person) applicationContext.getBean(beanName);
                System.out.println(person);
            }
        }
    }
}

运行结果:

// .....
org.springframework.context.event.internalEventListenerFactory
addBeanConfiguration
myPerson
Person(name=null)
myCat
Cat(person=Person(name=null))

4.2 删除-BeanFactoryPostProcessor

实体类的话还是沿用上面的两个,但是会利用自定义 BeanFactoryPostProcessor 来完成 BeanDefinition 的删除。

BeanFactoryPostProcessor:

@Component
public class CatBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) beanFactory;
        // 遍历IOC容器中的所有BeanDefinition,如果 beanDefinitionName 带 Cat,则干掉
        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
            if (beanDefinitionName.contains("Cat")){
                beanDefinitionRegistry.removeBeanDefinition(beanDefinitionName);
            }
        }
    }
}

配置类:

@ComponentScan(basePackages = "com.github.howinfun.demo.ioc.bean_definition")
@Configuration
public class RemoveBeanDefinitionConfiguration {

    @Bean
    public Person myPerson(){
        return new Person().setName("winfun");
    }

    @Bean
    public Cat myCat(Person myPerson){
        return new Cat().setPerson(myPerson);
    }
}

应用:

public class Application {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(RemoveBeanDefinitionConfiguration.class);
        String[] beanNames = applicationContext.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            System.out.println(beanName);
            if (beanName.contains("Cat")){
                Cat cat = (Cat) applicationContext.getBean(beanName);
                System.out.println(cat);
            }
            if (beanName.contains("Person")){
                Person person = (Person) applicationContext.getBean(beanName);
                System.out.println(person);
            }
        }
    }
}

运行结果:

// ......
removeBeanDefinitionConfiguration
catBeanFactoryPostProcessor
myPerson
Person(name=null)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值