【@ConditionalOnMissingBean】进行判断时对应的bean一定要实例化吗?
1、根据源码的追踪结果看是不需要的,只要存在对应类型的bean定义就算符合。在通过方法【doGetBeanNamesForType】在【BeanFactory】中查找已存在的bean时,遍历的是其bean定义集合【beanDefinitionNames】,而不是已经实例化的Bean集合【singletonObjects】,并且在通过方法【isTypeMatch】进行类型比对时,也是也是对bean定义名称和目标类型进行的。
2、当通过方法【isTypeMatch】进行比对时,如果当前Bean定义名称存在实例对象,则直接用该实例进行比对。如果不存在实例对象,则会对该Bean定义进行类型推断,如果推断结果【predictedType】与由Bean定义自身属性【targetType】和【factoryMethodReturnType】组合的【definedType】相同,则采用自身属性的类型,然后进行最终的类型比对。
3、在这个比对过程中可以看到,【BeanFactory】中Bean定义和Bean实例其实具有相同的地位,在Bean实例未实例化出来时,可以采用其Bean定义进行替代。Bean定义就是Bean实例的蓝本,所有的Bean实例都是根据Bean定义来的,两者之间存在一一对应的关系。
4、在获取匹配结果时,会先构建一个搜索Bean的指导说明【Spec】。
这个指导说明【Spec】的最重要作用,是确定在【BeanFactory】中要到底查找到一个什么样的Bean,这个Bean的名字是什么又或者类型是什么。【@ConditionalOnMissingBean】的属性【name】用来指定目标Bean的名字,属性【value】和【type】用来指定目标Bean的类型,如果这三个属性都不存在,则会通过推到方法【deducedBeanType】将@Bean方法的返回值类型作为目标Bean的类型。
也可以将【@ConditionalOnMissingBean】的属性【annotation】作为Bean的筛选条件。
最后会对用于查找Bean的指导说明属性进行检查【validate】。如果既没获取筛选的类型,也没指定Bean的名称,还没设置要筛选的Bean注解,则说明无法进行匹配查询,直接抛出错误。
在后续获取匹配结果的过程中,指导说明【Spec】的各项属性都会依次参与比对过程。