阅读前须知:需要有一定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有什么具体功能,请看下一节