Spring底层分析--2.BeanFactory的实现

一.举例

1.创建三个类

 @Configuration
    static  class Config{

        @Bean
        public A beanA(){
            return new A();
        }
        @Bean
        public B beanB(){
            return new B();
        }

    }

 static class A{
        public A(){
           log.info("调用了A的构造方法");
        }
    }

  static class B{

        @Autowired
        private A a;

        public B(){
          log.info("调用了B的构造方法");
        }


  }

2.创建beanFactory

 public static void main(String[] args) {

        //1.获取beanFactory
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

        //2.bean的定义,单例模式,类型
        AbstractBeanDefinition beanDefinition =
                BeanDefinitionBuilder.genericBeanDefinition(Config.class)
                        .setScope("singleton").getBeanDefinition();

        //3.给beanFactory添加定义器
        beanFactory.registerBeanDefinition("config",beanDefinition);

        //3.给beanFactory添加一些常用注解处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        //4.给beanFactory添加后处理器
        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().stream()
                .forEach(postProcessor -> {
                    postProcessor.postProcessBeanFactory(beanFactory);
                });

        //6.打印注入到容器中的bean
        for (String name : beanFactory.getBeanDefinitionNames()) {
            System.out.println(name);
        }

    }

运行结果

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
beanA
beanB

可以看到beanFactory把Config,A,B的对象都创建出来了

我们可以看到在B类中通过@AutoWired自动注入了A,那么我们来尝试获取这个A对象,看是否可以获取到它

  A beanA = beanFactory.getBean(B.class).a;
        System.out.println(beanA);

运行结果:

null

发现并没有创建这个A的对象,这是因为beanFactory没有实现对@Autowried的实现,我们需要添加bean的后处理器

3.bean后处理器


        //7.添加bean的后处理器
        beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor);

        //获取A
        A a = beanFactory.getBean(B.class).a;
        System.out.println(a);

运行结果:

21:47:19.239 [main] INFO com.example.springioc.component.TestBeanFactory - 调用了B的构造方法
21:47:19.244 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'beanA'
21:47:19.245 [main] INFO com.example.springioc.component.TestBeanFactory - 调用了A的构造方法
com.example.springioc.component.TestBeanFactory$A@d9345cd

可以看到这次成功创建了A的对象

4.bean的延迟创建

beanFactory会的bean的创建延迟,查看一下执行顺序,在获取A对象之前添加分隔符

运行查看结果:

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
beanA
beanB
21:49:00.784 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
21:49:00.785 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
--------------------------
21:49:00.788 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'beanB'
21:49:00.789 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'config'
21:49:00.799 [main] INFO com.example.springioc.component.TestBeanFactory - 调用了B的构造方法
21:49:00.804 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'beanA'
21:49:00.805 [main] INFO com.example.springioc.component.TestBeanFactory - 调用了A的构造方法
com.example.springioc.component.TestBeanFactory$A@d9345cd

可以看到刚开始只是声明了bean的定义,并没有创建bean对象,调用getBean()时才创建了bean对象

下面我们调用

//8.让bean对象提前创建
        beanFactory.preInstantiateSingletons();

再次运行查看结果:

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
beanA
beanB
21:53:08.726 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
21:53:08.727 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
21:53:08.730 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'config'
21:53:08.733 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'beanA'
21:53:08.740 [main] INFO com.example.springioc.component.TestBeanFactory - 调用了A的构造方法
21:53:08.741 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'beanB'
21:53:08.741 [main] INFO com.example.springioc.component.TestBeanFactory - 调用了B的构造方法
--------------------------
com.example.springioc.component.TestBeanFactory$A@5a45133e

进程已结束,退出代码0

可以看到在定义完bean之后就创建了bean对象

二.Autowired和Resource的顺序

1.Autowired注入

我们知道这俩注解都是实现依赖注入的,那么他们的顺序是怎样的?

我们定义C和D类,让它们都实习Com接口

  interface  Com{}
  
    static class C implements Com{
        public C(){log.info("调用了C的构造方法");}
    }
    static class D implements Com{
        public D(){log.info("调用了D的构造方法");}
    }

}

然后我们创建E类,给它注入Com类型的成员变量

  static class E{
        @Autowired
      private Com beanC;

        public E(){log.info("调用了E的构造方法");}
  }

把C,D,E都写入Config配置类中:

        @Bean
        public C beanC(){
            return new C();
        }
        @Bean
        public D beanD(){
            return new D();
        }
        @Bean
        public E beanE(){
            return new E();
        }

那么C和D都实现了Com接口,我们知道Spring是单例模式的,现在有两个一样类型的bean,最终会注入哪个bean呢?我们只需要把变量名字写为c,它最终就会注入C类型的bean

2.@Autowired的规则

1.首先按照bean的类型注入

2.如果bean的类型一样有多个,那么按照bean的名字注入

我们运行一下,看一下是哪个类型的bean被注入了:

com.example.springioc.component.TestBeanFactory$C@6fdbe764

可以看到注入了C类型的bean!

3.@Qualifer注解

我们还可以添加@Qualifer注解来限定是哪个bean

      @Autowired
      @Qualifier("beanC")
      private Com beanC;

4.同时添加两个注解

如果我们添加了两个注解,那么谁会注入进来呢?

      @Autowired
      @Resource(name = "beanD")
      private Com beanC;

我们@Resource指定要注入beanD,@Autowired指定要注入beanC

查看运行结果:

com.example.springioc.component.TestBeanFactory$C@1e0b4072

可以看到最终注入了C类型的bean,这是为什么呢?让我们查看bean后处理器的添加顺序:

 //7.添加bean的后处理器
        beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach((beanPostProcessor -> {
            beanFactory.addBeanPostProcessor(beanPostProcessor);
            System.out.println("=====>"+beanFactory);
        }));

查看运行结果:

=====>org.springframework.beans.factory.support.DefaultListableBeanFactory@13c10b87: defining beans [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,beanA,beanB,beanC,beanD,beanE]; root of factory hierarchy

我们可以看到internalAutowiredAnnotationProcessorinternalCommonAnnotationProcessor的前面添加,所有先把@Autowired注入,在@Resource之前

那么我们如何改变加载顺序呢?我们可以使用比较器来改变加载顺序:

    beanFactory.getBeansOfType(BeanPostProcessor.class).values().stream().sorted(
                        beanFactory.getDependencyComparator()
                )
                .forEach((beanPostProcessor -> {
            beanFactory.addBeanPostProcessor(beanPostProcessor);
            System.out.println("=====>"+beanFactory);
        }));

我们在查看运行结果:

com.example.springioc.component.TestBeanFactory$D@4686afc2

可以看到注入了D类型的对象

原理就是调用了setOrder()方法,对其设置了优先级,使@Resource的优先级在@Autowired之前了

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值