BeanFactory 的实现以及常见 ApplicationContext 实现

BeanFactory实现

DefaultListableBeanFactory

DefaultListableBeanFactory,是 BeanFactory 最重要的实现,像控制反转依赖注入功能,都是它来实现

image20220323203141800

下面我们试着自己实现一下Bean的注入

public class TeastBeanFactory1 {
    public static void main(String[] args) {
        // 首先我们定义一个DefaultListableBeanFactory
        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("构造 Bean1()");
        }

        @Autowired
        private Bean2 bean2;

        public Bean2 getBean2() {
            return bean2;
        }
    }

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

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

此时运行打印结果只有一个bean的名字 config

image20220323204214442

但是因为我们的代码中也有写@Configuration注解,然后配置类中也进行了bean注入,为什么没有其他的bean呢?

这就说明我们的注解没有被解析!!也就是说DefaultListableBeanFactory没有解析注解的能力!

那么怎么能让它的功能变得完整呢?答案就是给 BeanFactory 添加一些常用的后处理器

后处理器入门

public class TeastBeanFactory1 {
    public static void main(String[] args) {
        // 首先我们定义一个DefaultListableBeanFactory
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        // bean 的定义(class, scope, 初始化, 销毁)
        AbstractBeanDefinition beanDefinition =
                BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
        // 注册
        beanFactory.registerBeanDefinition("config", beanDefinition);
        // 给 BeanFactory 添加一些常用的后处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        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("构造 Bean1()");
        }

        @Autowired
        private Bean2 bean2;

        public Bean2 getBean2() {
            return bean2;
        }
    }

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

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

注意此时只是加入了后处理器,还并没有对注解进行处理

此时的输出只是多了几个后处理器的bean

image20220323205223012

下面添加运行后处理器的代码

public class TeastBeanFactory1 {
    public static void main(String[] args) {
        // 首先我们定义一个DefaultListableBeanFactory
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        // bean 的定义(class, scope, 初始化, 销毁)
        AbstractBeanDefinition beanDefinition =
                BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
        // 注册
        beanFactory.registerBeanDefinition("config", beanDefinition);
        // 给 BeanFactory 添加一些常用的后处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        // BeanFactory 后处理器主要功能,补充了一些 bean 定义
        // BeanFactoryPostProcessor是internalConfigurationAnnotationProcessor后处理器的类型
        // 这里就是运行这些后处理器
        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor -> {
            beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
        });

        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("构造 Bean1()");
        }

        @Autowired
        private Bean2 bean2;

        public Bean2 getBean2() {
            return bean2;
        }
    }

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

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

输出

image20220323205715074

现在我们将bean1和bean2都注入到了我们的beanfactory了,那我们再来试一试能否获得到我注入到bean1中的bean2呢?

image20220323211158159

我添加了如上代码

运行结果

image20220323210254878

我们看到了bean1的初始化,可是bean2是null,这说明我们的Autowired注解没有生效

我又又 运行了bean后处理器

image20220323211056735

运行结果

image20220323211220363

bean2成功获取到

单例对象的创建时机

我们在代码中添加一条分割线,观察输出

image20220323211519633

我们看到beanfactory中注入的对象都是懒加载的

我们想让他在调用之前就创建,效果如下

image20220323211754636

bean后处理器的顺序

我们从代码的这一行的方法进去

image20220323212839180

看到了添加bean后处理器的方法

image20220324212059017

我想知道@Resource和@Autowired的执行顺序

public class TeastBeanFactory1 {
    public static void main(String[] args) {
        // 首先我们定义一个DefaultListableBeanFactory
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        // bean 的定义(class, scope, 初始化, 销毁)
        AbstractBeanDefinition beanDefinition =
                BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
        // 注册
        beanFactory.registerBeanDefinition("config", beanDefinition);
        // 给 BeanFactory 添加一些常用的后处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        // BeanFactory 后处理器主要功能,补充了一些 bean 定义
        // BeanFactoryPostProcessor是internalConfigurationAnnotationProcessor后处理器的类型
        // 这里就是运行这些后处理器
        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor -> {
            beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
        });

        // Bean 后处理器, 针对 bean 的生命周期的各个阶段提供扩展, 例如 @Autowired @Resource ...
        beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor);

        for (String name : beanFactory.getBeanDefinitionNames()) {
            System.out.println(name);
        }
        beanFactory.preInstantiateSingletons();// 准备好所有的单例
        System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        //System.out.println(beanFactory.getBean(Bean1.class).getBean2());
        System.out.println(beanFactory.getBean(Bean1.class).getInter());

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

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

        @Bean
        public Bean3 bean3() {
            return new Bean3();
        }

        @Bean
        public Bean4 bean4() {
            return new Bean4();
        }
    }

    interface Inter {

    }

    static class Bean3 implements Inter {

    }

    static class Bean4 implements Inter {

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

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

        @Autowired
        private Bean2 bean2;

        public Bean2 getBean2() {
            return bean2;
        }

        @Autowired
        @Resource(name = "bean4")
        private Inter bean3;

        public Inter getInter() {
            return bean3;
        }

    }

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

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

我新增了两个bean,bean3和bean4

然后向bean1中用两种方式注入bean3和bean4,通过bean1.getInter()方法来测试优先级

结果如下:

image20220323213707430

@Autowired优先

我又又改了一下bean后处理器的运行方法,输出了一下后处理器

image20220323214029134

再次证明!

另外这个顺序也是可以改的,通过

image20220323214456880

这样改完顺序就会改变

原因是两个后处理器都实现了Order接口,都有一个决定优先级的order,调用这个方法后就根据order重新排序了。

常见 ApplicationContext 实现

ClassPathXmlApplicationContext

image20220325132805117

类的定义

image20220325132900360

结果

image20220325133309647

FileSystemXmlApplicationContext

image20220325134117362

如何使用BeanFactory实现上述两种ApplicationContext

image20220325140604463

AnnotationConfigApplicationContext

image20220325141623969

image20220325142248380

我们可以看到,相比较前两种ApplicatContext,AnnotationConfigApplicationContext的bean容器中多了后处理器和config对象

正是这些后处理器帮忙识别被注解的类和方法,实现的bean注入

那么,ClassPathXmlApplicationContext如何加载这些后处理器呢?

只需要在xml文件中加入一行<context:annotation-config/>

AnnotationConfigServletWebServerApplicationContext

image20220325153311256

运行结果

image20220325153705333

访问

image20220325153459764

学到了什么

​ a. 常见的 ApplicationContext 容器实现
​ b. 内嵌容器、DispatcherServlet 的创建方法、作用

posted @ 2022-03-31 22:16  liumeng哈哈哈  阅读(76)  评论(0编辑  收藏  举报