Spring源码02: BeanFactory实现

BeanFactory默认是由DefaultListableBeanFactory实现的

直接上代码加注释

public class TestFactory {
    public static void main(String[] args) {
        //刚创建是空的
        DefaultListableBeanFactory beanFactory =new DefaultListableBeanFactory();
        //需要去定义bean 类型 单例/多例 初始化 销毁
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Config.class)
                .setScope("singleton")
                .getBeanDefinition();
        //将定义 塞到bean工厂类 前面是bean的名称
        beanFactory.registerBeanDefinition("config",beanDefinition);

        //添加一些常见后处理器 因为beanFactory是没有读取注解来塞到bean的能力的
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        //把这些后处理器拿出来 执行一下推到bean工厂 这一块主要是进行bean的定义
        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor -> {
            System.out.println(beanFactoryPostProcessor);
            beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
        });

        //Bean 后处理器 针对bean的生命周期的各个阶段提供扩展, 例如@Autowired @Resource
        //修改排序规则 时AutoWired注解在Resource注解后面
        beanFactory.getBeansOfType(BeanPostProcessor.class).values().stream()
                .sorted(Objects.requireNonNull(beanFactory.getDependencyComparator()))
                .forEach(beanPostProcessor -> {
            System.out.println(">>>>"+beanPostProcessor);
            beanFactory.addBeanPostProcessor(beanPostProcessor);
        });

        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
        //在一开始就初始化单例对象
        beanFactory.preInstantiateSingletons();
        System.out.println(">>>>>>>>>>>>>>看一下类创建的先后顺序,注释上面一行>>>>>>>>>>>>");
        //懒加载 在需要时才会去创建类
        Bean1 bean1 = beanFactory.getBean(Bean1.class);
        System.out.println(bean1.getBean2());
        System.out.println(bean1.getInter());
    }

    @Configuration
    static class Config{
        @Bean
        public Bean1 bean1(){
            return new Bean1();
        }
        @Bean
        public Bean2 bean2(){
            return new Bean2();
        }
        @Bean
        public Inter bean3(){
            return new Bean3();
        }
        @Bean
        public Inter bean4(){
            return new Bean4();
        }
    }


    static class Bean2{
        public Bean2(){
            System.out.println("bean2 构造");
        }
    }
    interface Inter{ }
    static class Bean3 implements Inter{
        public Bean3(){
            System.out.println("bean3 构造");
        }
    }
    static class Bean4 implements Inter{
        public Bean4(){
            System.out.println("bean4 构造");
        }
    }
    static class Bean1{
        @Autowired
        private Bean2 bean2;
        //bean3和bean4同时继承Inter
        //用会注入哪一个
        @Autowired//两个一起注入时,按默认优先级会去Autowired
        //因为都返回了接口类 所以Autowired不知道用哪一个
        @Resource(name="bean4")//如果用了name 这里的优先级比较高 所以即使下面的属性名叫bean3 依然会注入bean4
        //private Inter inter;
        //可以直接改属性名 就会通过名称获取
        private Inter bean3;
        public Bean1(){
            System.out.println("bean1 构造");
        }

        public Bean2 getBean2() {
            return bean2;
        }
        public Inter getInter(){
            return bean3;
        }
    }
}

很多事其实BeanFactory不会主动去做,

  1. 不会主动调用BeanFactory的后处理器
  2. 不会主动添加Bean后处理器
  3. 不会主动初始化单例对象
  4. 不会解析beanFactory 不会解析${} 与#{}

这些东西如果不自动去做,对于初级程序员来说学习成本比较高, 所以就有了ApplicatinContext来整合帮我们去做.

再补充一下 在前面的添加后处理器时,会添加排序规则

AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

里面添加了比较器对象
在这里插入图片描述](https://img-blog.csdnimg.cn/793eec5401274b6bb5056f9c61d7097a.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASmF2YeWFheeUteahqQ==,size_20,color_FFFFFF,t_70,g_se,x_16

在两个后处理器中是通过 getOrder方法来进行排序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值