Spring精讲:什么是BeanFactory?(附源码)( 二 )


BeanDefinition其实是一个接口 , 并不是一个具体的类 , 我们也可以看一下它的UML图:
Spring精讲:什么是BeanFactory?(附源码)文章插图
可以发现这里使用了模板方法的设计模式扩展了许多的子类 , 其中我们最常用的为RootBeanDefinition , 它主要包含的属性如下:
Spring精讲:什么是BeanFactory?(附源码)文章插图
我们向容器中注册的Bean定义的信息大概就是如此 , 当BeanFactory生产Bean时 , 便可以通过beanClass清楚的知道Bean的类是什么 , 作用域是怎样 , 是否懒加载 , init方法是什么等等等等
> 咦 , 如果一个最简单的bean , 好像可以直接通过反射就搞定了耶~
具体结构已经清楚了 , 那我们来看一下注册过程吧
先从Demo看起public static void main(String[] args) {//创建一个DefaultListableBeanFactory实例DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();//创建一个BeanDefinitionRootBeanDefinition beanDefinition = new RootBeanDefinition(Wheel.class);//将BeanDefinition注册到容器中beanFactory.registerBeanDefinition("wheel",beanDefinition);}public static class Wheel {}创建BeanDefinitionpublic RootBeanDefinition(@Nullable Class beanClass) {//初始化父类super();//将beanClass赋值给this.BeanClasssetBeanClass(beanClass);}初始化父类
//将其中一部分属性赋予默认值autowireCandidate = true;primary = false;protected AbstractBeanDefinition() {this(null, null);}protected AbstractBeanDefinition(@Nullable ConstructorArgumentValues cargs, @Nullable MutablePropertyValues pvs) {this.constructorArgumentValues = cargs;this.propertyValues = pvs;}将BeanDefinition注册到容器中//除去校验逻辑 , 注册时只做了这两步操作this.beanDefinitionMap.put(beanName, beanDefinition);this.beanDefinitionNames.add(beanName);看到这里 , 大家伙可能会充满疑问?what? 就这样?没有填充属性的步骤吗?嘿嘿 , BeanFactory是一个纯粹的工厂 , 只负责生产Bean , 是没有装配(设计)BeanDefinition的功能的 , 专业的事还是交给专业的人做 , 设计的事情还是交由ApplicationContext完成的 。
那在ApplicationContext中是怎么完成一个BeanDefinition的呢?还记得预启动将配置类注册到容器中时有这样一段代码吗?以下代码为AnnotatedBeanDefinitionReader#doRegisterBean中的摘要部分:
void doRegisterBean(Class annotatedClass, @Nullable Supplier instanceSupplier, @Nullable String name,@Nullable Class[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) { //.......代码//处理普通的bean定义注解 , @Lazy @Primary @DependsOn @Role @DescriptionAnnotationConfigUtils.processCommonDefinitionAnnotations(abd);//......代码} 而非配置的Bean是通过在预启动时注册的配置类后置处理器ConfigurationClassPostProcessor#processConfigBeanDefinitions中完成的 , 以下代码为ClassPathBeanDefinitionScanner#doScan中的摘要部分 , 详细调用链将在后面的文章进行说明
//传入我们配置类的包路径protected Set doScan(String... basePackages) {Set beanDefinitions = new LinkedHashSet<>();for (String basePackage : basePackages) {//寻找到所有标识了@Component注解的BeanDefinitionSet candidates = findCandidateComponents(basePackage);for (BeanDefinition candidate : candidates) {//....省略代码if (candidate instanceof AbstractBeanDefinition) {//处理BeanDefinitionpostProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);}if (candidate instanceof AnnotatedBeanDefinition) { //处理普通的bean定义注解 , @Lazy @Primary @DependsOn @Role @DescriptionAnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);}//...省略代码//将BeanDefinition注册到容器中registerBeanDefinition(definitionHolder, this.registry);} }


推荐阅读