容器接口

BeanFactory
- 是ApplicationContext的父接口,所有ApplicationContext的实现都组合了BeanFactory。
- BeanFactory才是Spring的核心容器。

从BeanFactory提供的方法来看,主要是从容器中获取Bean。实际上控制反转,依赖注入以及Bean的生命周期管理,都由它的实现类提供。如下展示了BeanFactory其中一个实现类DefaultListableBeanFactory的继承关系。

可以看到,它的继承路线上有一个DefaultSingletonBeanRegistry类,这个类我们打开可以看到如下代码段,其中singletonObjects对象正是容器中所有单例对象被保存的地方。- public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
- /** Cache of singleton objects: bean name to bean instance. */
- private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); // 保存了所有的单例对象
- /** Cache of singleton factories: bean name to ObjectFactory. */
- private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
-
- ...
- }
复制代码 通常我们会使用如下方式来启动和加载Spring容器- @SpringBootApplication
- public class SsmpApplication {
- public static void main(String[] args) throws IOException {
- final ConfigurableApplicationContext context = SpringApplication.run(SsmpApplication.class, args);
- // MessageSource接口提供的功能,实现国际化能力
- context.getMessage("hi", null, Locale.CHINA);
- context.getMessage("hi", null, Locale.US);
- // ResourcePatternResolver接口提供的能力,实现读取资源文件的能力
- final Resource[] resources = context.getResources("classpath*:spring.factories");
- // EnvironmentCapable接口提供的能力,实现获取环境参数的能力,可以获取环境变量、配置等
- final String java_home = context.getEnvironment().getProperty("java_home");
- final String port = context.getEnvironment().getProperty("server.port");
- // ApplicationEventPublisher提供的能力,可以发送事件,实现解耦
- context.publishEvent(new MyEvent(context));
- }
- public static class MyEvent extends ApplicationEvent {
- public MyEvent(Object source) {
- package com.leo.domain;
- import lombok.Data;
- @Data
- public class Book {
- private Integer id;
- private String type;
- private String name;
- private String description;
- }super(source);
- }
- }
- }
复制代码 其内部实现如果简单的拆开来,可以用如下步骤表示,BeanFactory是真正的容器,我们使用XmlBeanDefinitionReader将xml中定义的bean转化成BeanDefinition并注册到BeanFactory中。以上代码的运行结果如下:- 10:56:43.379 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
- 10:56:43.395 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor'
- 10:56:43.398 [main] INFO com.leo.ssmp.SsmpApplication - ---------------BeanFactory后处理器------------------
- 10:56:43.398 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.context.annotation.ConfigurationClassPostProcessor@724af044
- 10:56:43.398 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.context.event.EventListenerMethodProcessor@4678c730
- 10:56:43.512 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory'
- 10:56:43.513 [main] INFO com.leo.ssmp.SsmpApplication - ---------------BeanFactory后处理器------------------
- 10:56:43.513 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
- 10:56:43.513 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
- 10:56:43.516 [main] INFO com.leo.ssmp.SsmpApplication - ----------------Bean后处理器-----------------
- 10:56:43.516 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor@6385cb26
- 10:56:43.516 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.context.annotation.CommonAnnotationBeanPostProcessor@38364841
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - ----------------Bean后处理器-----------------
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - ------------------注册的所有Bean定义信息------------------
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - config
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.context.annotation.internalConfigurationAnnotationProcessor
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.context.annotation.internalAutowiredAnnotationProcessor
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.context.annotation.internalCommonAnnotationProcessor
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.context.event.internalEventListenerProcessor
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.context.event.internalEventListenerFactory
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - bean1
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - bean2
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - ------------------注册的所有Bean定义信息------------------
- 10:56:43.517 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bean1'
- 10:56:43.518 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'config'
- 10:56:43.529 [main] INFO com.leo.ssmp.SsmpApplication - Bean1 construct...
- 10:56:43.535 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bean2'
- 10:56:43.536 [main] INFO com.leo.ssmp.SsmpApplication - Bean2 construct
- 10:56:43.537 [main] INFO com.leo.ssmp.SsmpApplication - com.leo.ssmp.SsmpApplication$Bean2@55040f2f
- Process finished with exit code 0
复制代码 我们会发现这是容器里只有一个Bean,但是当我们用springboot自动配置来启动容器时,会发现即使我们不定义Bean,默认也会加载一些内置的bean。那么Spring是如何加载这些内置的Bean的呢。我们可以在xml文件中加入如下配置:- package com.leo.domain;
- import lombok.Data;
- @Data
- public class Book {
- private Integer id;
- private String type;
- private String name;
- private String description;
- }
复制代码 这样我们运行上面的代码时打印出来的结果如下:- 10:56:43.379 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
- 10:56:43.395 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor'
- 10:56:43.398 [main] INFO com.leo.ssmp.SsmpApplication - ---------------BeanFactory后处理器------------------
- 10:56:43.398 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.context.annotation.ConfigurationClassPostProcessor@724af044
- 10:56:43.398 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.context.event.EventListenerMethodProcessor@4678c730
- 10:56:43.512 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory'
- 10:56:43.513 [main] INFO com.leo.ssmp.SsmpApplication - ---------------BeanFactory后处理器------------------
- 10:56:43.513 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
- 10:56:43.513 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
- 10:56:43.516 [main] INFO com.leo.ssmp.SsmpApplication - ----------------Bean后处理器-----------------
- 10:56:43.516 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor@6385cb26
- 10:56:43.516 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.context.annotation.CommonAnnotationBeanPostProcessor@38364841
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - ----------------Bean后处理器-----------------
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - ------------------注册的所有Bean定义信息------------------
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - config
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.context.annotation.internalConfigurationAnnotationProcessor
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.context.annotation.internalAutowiredAnnotationProcessor
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.context.annotation.internalCommonAnnotationProcessor
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.context.event.internalEventListenerProcessor
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - org.springframework.context.event.internalEventListenerFactory
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - bean1
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - bean2
- 10:56:43.517 [main] INFO com.leo.ssmp.SsmpApplication - ------------------注册的所有Bean定义信息------------------
- 10:56:43.517 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bean1'
- 10:56:43.518 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'config'
- 10:56:43.529 [main] INFO com.leo.ssmp.SsmpApplication - Bean1 construct...
- 10:56:43.535 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bean2'
- 10:56:43.536 [main] INFO com.leo.ssmp.SsmpApplication - Bean2 construct
- 10:56:43.537 [main] INFO com.leo.ssmp.SsmpApplication - com.leo.ssmp.SsmpApplication$Bean2@55040f2f
- Process finished with exit code 0org.springframework.context.annotation.internalConfigurationAnnotationProcessororg.springframework.context.annotation.internalAutowiredAnnotationProcessororg.springframework.context.annotation.internalCommonAnnotationProcessororg.springframework.context.event.internalEventListenerProcessororg.springframework.context.event.internalEventListenerFactory
复制代码 可以看到这时已经加载了很多处理注解和事件监听的Bean。
FileSystemXmlApplicationContext
基本原理与ClassPathXmlApplicationContext相似,只不过这里改为从文件系统直接读取xml配置。
AnnotationConfigApplicationContext
直接通过@Configuration注解的类来加载Bean,这种方法加载Bean时,会默认加载注解处理器这些内置的Bean。同时还会将config类也加载为Bean。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |