Bootstrap

【Spring源码】1.1 BeanFactory和ApplicationContext

阅读前须知:需要有一定Spring基础和Spring实践经验

1.1 ApplicationContext功能

在我们熟知的用于启动Spring的Spring引导启动类中,有一个熟悉的类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
    }
}

其中ConfigurableApplicationContext是继承自ApplicationContext类的,而ApplicationContext类的继承类图如下:

可以看到,ApplicationContext类继承了EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource,ApplicationEventPublisher, ResourcePatternResolver这几个类,其中每一个类对应了AppplicationContext的一个功能。

EnvironmentCapable
该类主要使得ApplicationContext可以获取Spring的一些配置信息,比如说:

        System.out.println(context.getEnvironment().getProperty("java_home"));
        System.out.println(context.getEnvironment().getProperty("server.port"));

通过如下的语句,可以获取并且打印出JAVA_HOME和服务器工作的端口

ApplicationEventPublisher
ApplicationEventPublisher是Spring自带的消息队列,相对于我们熟知的rabbitMQ,ApplicationEventPublisher不支持分布式,因此一般只在自己的单体系统中使用。

详情请见:
https://blog.csdn.net/suifeng0614/article/details/128302518

MessageSource
MessageSource是Spring的国际化支持功能,主要用于为页面提供多种语言。平时我们在网站看到的多语言切换就是使用MessageSource实现的,具体实现参见下文:
https://blog.csdn.net/qq_43203949/article/details/125471825

ResourcePatternResolver
ResourcePatternResolver是Spring里的一个资源解析器,可以查找Spring项目下的资源,ApplicationContext可以调用getResource()方法实现资源查找,比如说查找application.properties配置文件,则使用以下代码

        // 在类路径下查找
        Resource[] resources = context.getResources("classpath:application.properties");
        for (Resource r: resources) {
            System.out.println(r);
        }
        // 如果要在磁盘查找,请使用context.getResources("file:路径+名称");

详细可见下文:
https://blog.csdn.net/qq_17229141/article/details/124291532

BeanFactory
可以看到,ApplicationContext通过ListableBeanFactory, HierarchicalBeanFactory间接继承了BeanFactory,而BeanFactory则是Spring中的一个关键机制,用于生产Bean。既然继承了BeanFactory,那么我们也可以使用ApplicationContext来实现BeanFactory的查找所有Bean功能,代码如下:

        // 获取ApplicationContext子类ConfigurableApplicationContext
        ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
        // 使用反射机制获取DefaultSingletonBeanRegistry中的singletonObjects
        Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
        // singletonObjects默认为private,修改权限为public
        singletonObjects.setAccessible(true);
        // 获取ApplicationContext的BeanFactory
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        Map<String, Object> map = (Map<String, Object>)singletonObjects.get(beanFactory);
        map.forEach((k,v)->{
            System.out.println(k+"="+v);
        });



总结来说,ApplicationContext是围绕着BeanFactory设计的,因为BeanFactory是Spring的核心机制,十分重要。而ApplicationContext在BeanFactory的基础上进一步拓展了资源查找,环境查找,文本国际化,消息队列和的功能。而至于BeanFactory有什么具体功能,请看下一节

;