您好,欢迎来到爱玩科技网。
搜索
您的当前位置:首页Spring容器的核心组件

Spring容器的核心组件

来源:爱玩科技网

一、背景

不妨大胆推测一下:Spring是如何处理我们的Bean的呢?

通过读取解析文件中的资源配置,将需要交给容器管理的类先找个地方集中起来(注册表),最后将这个注册表中所有的Bean定义实例化为Bean。

将Bean在内存中缓存起来(HashMap),在我们需要使用的时候根据key值直接取出来我们的对象。事实上,Spring的确也是这么处理的。

只不过它的设计远比我们所能想到的更要复杂与全面。

二、认识一下BeanFactory

我们知道Spring使用BeanFactory来产生和管理Bean。

@Component
   public class MyCompBean { 
     private String name="myCompBean";
   }

   @SpringBootApplication
   public class BootStarter {

      public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(BootStarter.class);
        //@Component
        Object myCompBean = context.getBean("myCompBean");
        System.out.println(myCompBean);
      }
   }

我们从SpringApplication.run()方法入手,发现默认创建了AnnotationConfigApplicationContext作为Spring的上下文。

如果依赖中有spring-boot-starter-web默认是创建SERVLET类型的AnnotationConfigServletWebServerApplicationContext

public ConfigurableApplicationContext run(String... args) {
    // 省略部分代码...
    context = this.createApplicationContext();
    // 省略部分代码...
}

protected ConfigurableApplicationContext createApplicationContext() {
        Class<?> contextClass = this.applicationContextClass;
        if (contextClass == null) {
            try {
                switch(this.webApplicationType) {
                case SERVLET:
                    contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");
                    break;
                case REACTIVE:
                    contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");
                    break;
                default:
                    contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext");
                }
            } catch (ClassNotFoundException var3) {
                throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);
            }
        }

        return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);
    }

下面我们先看一下该类的UML图然后再逐步分析Bean的存储路径。

下面我们看一下Bean(单例)获取的时序图(Spring完全加载完成之后)

最终我们发现我们从容器中获取的Bean是从DefaultSingletonRegistry的singletonObjects中拿到的。

我们看看这个是什么。没错!它就是一个Map。(有没有觉得Spring不过如此?千万别这么想,你可知为了让咱使用起来尽量简单,它做了太多的工作。)

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);
}

三、主角登场

DefaultListableBeanFactory是整个Bean加载的核心部分,是 Spring 注册及加载Bean的默认实现。

它继承了 AbstractAutowireCapableBeanFactory 并实现了ConfigurableListableBeanFactory以及BeanDefinitionRegistry接口 。

可以看出来,层次还是相当清晰的,我们先粗略的看看这些类都具备哪些功能。

  • AliasRegistrγ: 定义对alias的简单增删改等操作。
  • SimpleAliasRegistry: 主要使用map作为alias的缓存,并对接口AliasRegistry 进行实现。
  • SingletonBeanRegistry:定义对单例的注册及获取 。
  • BeanFactory:定义获取Bean及Bean的各种属性 。
  • DefauItSingletonBeanRegistry:对接口SingletonBeanRegistry各函数的实现。
  • HierarchicalBeanFactory:继承 BeanFactory,也就是在 BeanFactory 定义的功能的基础上增加了对 parentFactory的支持 。
  • BeanDefinitionRegistry: 定义对 BeanDefinition 的各种增删改操作 。
  • FactoryBeanRegistrySupport:在DefaultSingletonBeanRegistry 基础上增加了对FactoryBean的特殊处理功能 。
  • ConfigurableBeanFactory:提供配直 Factory 的各种方法 。
  • ListableBeanFactory:根据各种条件获取Bean的配置清单 。
  • AbstractBeanFactory:综合FactoryBeanRegistrySupport和ConfigurableBeanFactory 的 功能。
  • AutowireCapableBeanFactory:提供创建 Bean、自动注入、初始化以及应用Bean的后处理器 。
  • AbstractAutowireCapableBeanFactory:综合AbstractBeanFactory并对接口AutowireCapableBeanFactory进行实现。
  • ConfigurableListableBeanFactory: Beanfactory配置清单,指定忽略类型及接口等。
  • DefaultListableBeanFactory: 综合上面所有功能,主要是对Bean注册后的处理 。

四、总结

我们基本上已经了解了Spring是使用BeanFactory将我们的Bean管理了起来。GenericApplicationContext通过持有了一个DefaultListableBeanFactory作为BeanFactory的默认实现。后续我们就要继续探索Spring是如何将我们的Bean加载到BeanFactory中去的。


因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- aiwanbo.com 版权所有 赣ICP备2024042808号-3

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务