ConfigurableListableBeanFactory和BeanDefinitionRegistry关系

本文探讨了Spring Boot中调用Refresh方法时涉及的BeanFactory处理流程。通过分析DefaultListableBeanFactory如何同时实现ConfigurableListableBeanFactory和BeanDefinitionRegistry接口,解释了框架内部对象类型判断的工作原理。

前言

:在查看springBoot源码的过程中,遇到了这个问题,上网查了一些资料,理解了一些,这里顺便把这个问题给记录一下。

在springBoot调用Refresh方法里面 ,有一个叫invokeBeanFactoryPostProcessors的方法【图1】
在这里插入图片描述
在它里面会判断当前的beanFactory是否是BeanDefinitionRegistry的示例【图2】,这里的入参显示的是ConfigurableListableBeanFactory
在这里插入图片描述
查看两者的继承以及实现关系,发现两者并没有太大联系【图三、图4】,于是进行了资料查询。
在这里插入图片描述
在这里插入图片描述

结果:

实体类DefaultListableBeanFactory既实现了ConfigurableListableBeanFactory接口,也实现了BeanDefinitionRegistry接口,而我们从AnnotationConfigServletWebApplicationContext中调用obtainFreshBeanFactory方法【图5】,返回给我们的其实就是DefaultListableBeanFactory对象【图6】。只不过框架用它的父类ConfigurableListableBeanFactory接住了这个对象,导致我在后续判断实例的场景中 误以为传入的是ConfigurableListableBeanFactory,也就导致了问题的产生。
在这里插入图片描述
在这里插入图片描述

疑问:

一个对象ClassAB继承两个不同的接口FaceA、FaceB,调用instanceof(B b)方法判断b instanceof A ,当传入对象是ClassAB时,会返回结果true吗?

验证

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
经过一个简单的测试,发现返回结果为true,这也就验证了前面的猜想。

不过到最后还想问一下各位大佬,上面这种机制在java里面有没有一个专业的名词来解释?

Spring框架中,`@Configuration``@Bean`注解通常用于静态声明式的配置方式,通过Java代码替代传统的XML配置文件来定义Bean。然而,在某些场景下,可能需要根据运行时条件动态地加载或注册Bean。为此,Spring提供了多种机制实现动态获取注册Bean的方式。 ### 条件化Bean加载 Spring提供了`@Conditional`注解,可以根据特定的条件决定是否创建某个Bean。通过自定义条件类实现`Condition`接口,并重写其`matches`方法,可以控制Bean的创建逻辑。 ```java public class MyCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { // 根据运行时条件判断是否匹配 return "someCondition".equals(System.getProperty("my.condition")); } } @Configuration public class ConditionalConfig { @Bean @Conditional(MyCondition.class) public MyBean myBean() { return new MyBean(); } } ``` 在上述例子中,只有当系统属性`my.condition`等于`someCondition`时,`myBean`才会被创建并注册到Spring容器中[^1]。 ### 动态注册Bean 如果需要在应用启动后动态地向Spring容器中注册新的Bean,可以通过`BeanDefinitionRegistry`接口实现这一目的。具体步骤包括: 1. 获取`BeanDefinitionRegistry`实例。 2. 创建`RootBeanDefinition`或使用`GenericBeanDefinition`描述要注册的Bean。 3. 调用`registerBeanDefinition`方法将Bean定义注册到容器中。 下面是一个简单的示例,展示如何在运行时动态注册一个Bean: ```java @Component public class DynamicBeanRegistrar implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; // 定义一个新的Bean GenericBeanDefinition beanDefinition = new GenericBeanDefinition(); beanDefinition.setBeanClassName("com.example.MyDynamicBean"); // 注册Bean到容器中 registry.registerBeanDefinition("myDynamicBean", beanDefinition); } } } ``` 在这个例子中,`DynamicBeanRegistrar`实现了`BeanFactoryPostProcessor`接口,在`postProcessBeanFactory`方法中动态地向Spring容器注册了一个名为`myDynamicBean`的新Bean[^2]。 ### 使用`ImportSelector`接口 另一种实现动态注册Bean的方法是利用`ImportSelector`接口。该接口允许在导入配置类时选择性地添加其他配置类,从而实现更灵活的模块化配置管理。 ```java public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { // 根据条件返回需要导入的配置类 return new String[]{"com.example.config.AnotherConfig"}; } } @Configuration @Import(MyImportSelector.class) public class ImportSelectorConfig { } ``` 这里,`MyImportSelector`会根据具体的业务逻辑决定应该导入哪些额外的配置类,进而影响最终注册到Spring容器中的Bean集合[^3]。 ### 相关问题 1. 如何使用Spring的`@Conditional`注解进行条件化Bean加载? 2. 在Spring框架中,怎样通过编程方式动态注册Bean? 3. 什么是`ImportSelector`接口?它能解决什么问题? 4. Spring框架支持哪些类型的条件评估策略? 5. 如果想要在不同的环境配置下使用不同的Bean实现,有哪些推荐的做法? 以上方法不仅能够帮助开发者构建更加灵活、可维护的应用程序结构,而且也为处理复杂的依赖关系提供了强有力的支持。通过合理运用这些技术,可以使应用程序更好地适应变化多端的实际需求场景。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值