原创

BeanFactory的实现


BeanFactory的实现

代码如下:

public class TestBeanFactory {

    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //bean的定义 (class,scope,初始化,销毁方法等)

        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();

        beanFactory.registerBeanDefinition("config",beanDefinition);

        for (String name : beanFactory.getBeanDefinitionNames()) {
            System.out.println(name);
        }
    }

    @Configuration
    static class Config {
        @Bean
        public Bean1 bean1() {return new Bean1();}

        @Bean
        public Bean2 bean2() {return new Bean2();}
    }

    static class Bean1 {
        private static final Logger log = LoggerFactory.getLogger(Bean1.class);

        public Bean1() {
            log.debug("构造方法");
        }
    }

    static class Bean2 {
        private static final Logger log = LoggerFactory.getLogger(Bean2.class);

        public Bean2() {
            log.debug("构造方法");
        }
    }
}

输出

config

Process finished with exit code 0

根据输出可以看出来,@Bean注解其实并没有被解析,

这时给BeanFactory加上一些后置处理器后

       //给BeanFactory添加一些常用的后处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        for (String name : beanFactory.getBeanDefinitionNames()) {
            System.out.println(name);
        }

输出如下,举几个常见的说一下:

  • internalConfigurationAnnotationProcessor - 看名字就知道是解析@Configurtion注解的
  • internalAutowiredAnnotationProcessor - 解析@autowired注解的
  • internalCommonAnnotationProcessor - 解析Resource等注解的
config
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory

Process finished with exit code 0

这时候,其实Bean1,Bean2还是没有加入到bean工厂里面去的,因为我们现在只是把这些后处理器加入到了BeanFactory,还没让它们起作用

我们让它与BeanFactory关联起来,

//给BeanFactory添加一些常用的后处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor -> {
    beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
});

这个时候就会发现,bean工厂多出来了两个bean ,bean1和bean2

config
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
bean1
bean2

Process finished with exit code 0

我们在Bean1中去依赖Bean2

static class Bean1 {
    private static final Logger log = LoggerFactory.getLogger(Bean1.class);

    public Bean1() {
        log.debug("构造方法");
    }

    @Autowired
    private Bean2 bean2;

    public Bean2 getBean2() { return  bean2;}
}

看一下BeanFactory有没有进行依赖注入

//给BeanFactory添加一些常用的后处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor -> {
    beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
});

for (String name : beanFactory.getBeanDefinitionNames()) {
    System.out.println(name);
}

System.out.println(beanFactory.getBean(Bean1.class).getBean2());

输出为null,所有可以看出来,其实BeanFactory也是没有对bean的一些后置处理器的,因为我们看看只是给beanFactory关联了一些BeanFactory的后置处理器,并没有关联Bean的后置处理器,所有无法完成Autowired依赖注入

config
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
bean1
bean2
17:06:59.585 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bean1'
17:06:59.587 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'config'
17:06:59.598 [main] DEBUG com.lbq.springstudy.a02.TestBeanFactory$Bean1 - 构造方法
null

Process finished with exit code 0

好,那我们把上面AnnotationConfigUtils提供了bean后置处理器也与beanFactory关联

//给BeanFactory添加一些常用的后处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
//将这些beanFactory后置处理器与BeanFactory关联
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor -> {
    beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
});
//将这些bean后置处理器与beanFactory关联
beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor);

for (String name : beanFactory.getBeanDefinitionNames()) {
    System.out.println(name);
}

再来打印就发现Bean2已经注入到Bean1里面去了

17:13:51.434 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bean1'
17:13:51.435 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'config'
17:13:51.450 [main] DEBUG com.lbq.springstudy.a02.TestBeanFactory$Bean1 - 构造方法
17:13:51.458 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bean2'
17:13:51.459 [main] DEBUG com.lbq.springstudy.a02.TestBeanFactory$Bean2 - 构造方法
com.lbq.springstudy.a02.TestBeanFactory$Bean2@29ba4338

其实细心一点,我们还可以发现,当没有进行依赖注入的时候,上面只打印了Bean1的构造方法,而加入之后,才打印Bean2,这说明什么呢,说明啊,beanFactory只要在用到bean的时候才会去实例化这个bean,就类似于一种懒加载的机制

Spring
  • 作者:刘柄岐
  • 发表时间: 2022-04-12 17:23
  • 版权声明:自由转载-非商用