spring context架构--静态结构

简介: 概念Context也就是我们常说的spring容器,打个比方,context就像是一家公司,beans则是公司的工厂,除了工厂,公司还有翻译,仓库以及办公场所等等。下面就看看context的主要构成部件。Context构成部件上图是ApplicationContext的实体静态结构,它继承了六个实体。虽然是继承,但其实context和他们的关系更像是聚

概念

Context也就是我们常说的spring容器,打个比方,context就像是一家公司,beans则是公司的工厂,除了工厂,公司还有翻译,仓库以及办公场所等等。

下面就看看context的主要构成部件。

Context构成部件

spring context

上图是ApplicationContext的实体静态结构,它继承了六个实体。虽然是继承,但其实context和他们的关系更像是聚合。Spring使用继承主要是为了在context上也同时体现这6个实体的特征。在实现层面,context事实上是个包装类,最终通过聚合的实体类完成相应行为,而ApplicationContext接口本身并没有什么实质意义的方法。

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
        MessageSource, ApplicationEventPublisher, ResourcePatternResolver {

    String getId();

    String getApplicationName();

    String getDisplayName();

    long getStartupDate();

    ApplicationContext getParent();

    AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}

ApplicationContext的实质功能都是继承于以下6个实体:

  1. MessageSource: 用于国际化的接口,可以将其理解为公司的翻译。用户可以通过bean配置自定义MessageSource–要求name为“messageSource”,spring会在容器refresh时自动探测并且初始化它。

  2. ApplicationEventPublisher: 用于发布应用事件,例如ContextRefreshed,stopped, started等。它就像是企业邮箱,通过它可以接收到公司的事件通知。用户通过配置ApplicationListener类型的bean即可订阅这类事件,spring通过getBeansOfType取得所有的listener,并依次通知。

  3. ResourcePatternResolver: 对ResourceLoader的扩展,后者只支持对具体路径资源的加载,而前者则支持对某pattern路径资源的加载,默认是ant风格的模式。Resource是特指配置文件,或者class路径(里的扫描路径)。我们可以将它理解为打单的机器,将各个地方发过来的单子打出来。

  4. ListableBeanFactory和HierachicalBeanFactory: 自然的context也是个工厂,context里持有的依然是DefaultListableBeanFactory,通过它完成工厂的相应行为。介绍下这两个工厂,前者主要用于取得批量bean,比如getBeansOfType;后一个工厂则主要体现层级概念,但是context的parentFactory也是一个context,这是因为context具有beanFactory的所有特征。

  5. EnviromentCapable: 则类似是公司的行政部门,负责办公场所等设施维护。它关联着Enviroment。Enviroment也类似context是个包装类,虽然继承了PropertyResolver,但在实现类里是委托给ConfigurablePropertyResolver处理的。Enviroment代表应用环境,比如测试环境还是生产环境又或者开发环境。
    用户可以通过或者@Profile指定某个配置的profile。然后通过activeProfile指定应用环境,从而会enable相应profile的beans
    activeProfile可以通过5种方式指定:
    1). servlet config init param,这种方式只适用于spring mvc的dispatcherServlet配置上
    2). servlet context init param
    3). system property
    4). system env。以上四种方式设置的key均为spring.profiles.active
    5.) @ActiveProfile,这种方式只适用于junit单元测试

Context通过继承获得了工厂,事件发布,环境定义,资源加载以及国际化的能力。

context静态结构

这一节我只抽一些比较重要的接口的源码讲述,主要还是注重概念和原理,后面会专门出一篇讲context的动态处理过程,那里面会对具体实现类做详述。这一篇泽主要是建立对context静态类结构的理解。

下图是web application context的类图,可以和构成部件的结构图结合着看,上面的图每个实体都是spring context的一个接口。
context类结构
常见的WebApplicationContext实现主要有两个,分别是XmlWebApplicationContext和AnnotationConfigWebApplicationContext。他们共同的父类为AbstractRefreshableWebApplicationContext,我们从它出发,看一下context的类结构。

LifeCycle和Closeable代表着容器的整个生命周期,被ConfigurableApplicationContext继承,使继承该接口的context具有生命周期的特征。

public interface Lifecycle {
    void start();

    void stop();

    boolean isRunning();
}

用户可以配置Lifecycle类型bean,在context start以及stop时也会相应的启动LifeCycle bean的start或者stop。对于允许autoStartup的SmartLifecycle,context refresh的过程中会自动启动。

ConfigurableApplicationContext继承了生命周期,代表一个可以修改相关属性行为的context,上一节提到的Enviroment和ApplicationListener等等都可以通过它设置。同时整个context的核心refresh方法也是定义在他里面,所以所有的context都继承了它。

public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {
       void setId(String id);

    void setParent(ApplicationContext parent);

    ConfigurableEnvironment getEnvironment();

    void setEnvironment(ConfigurableEnvironment environment);

//添加bean后处理器,[beans架构](http://blog.csdn.net/szwandcj/article/details/50688616)架构里详细讲过后处理器
       void addBeanFactoryPostProcessor(BeanFactoryPostProcessor beanFactoryPostProcessor);

    void addApplicationListener(ApplicationListener<?> listener);

//context核心方法,refresh是整个容器构建的过程
    void refresh() throws BeansException, IllegalStateException;

//注册jdk进程退出时的hook
    void registerShutdownHook();

    void close();

    boolean isActive();

    ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
}

实现这个接口的AbstractApplicationContext很自然的也承担了context的绝大部分职能,上一节提过的context的六个方面的功能就几乎都是由它实现,除BeanFactory以外,其它的4个实体都是聚合在这个类里。而DefaultListableBeanFactory–那个最著名的BeanFactory则是由它的子类AbstractRefreshableApplicationContext生成,它自己通过模板方法使用。

AbstractRefreshableApplicationContext定义了loadBeanDefinitions模板方法,由具体的实现提供。它创建bean factory并load配置文件。beans配置文件load过程参考这里

AbstractRefreshableConfigApplicationContext主要用于设置资源的路径。几乎所有的ApplicationContext都会继承这个类,除非不需要读取配置资源。

AbstractRefreshableWebApplicationContext主要针对web的一些特性提供一些context属性行为设置能力,例如覆盖默认的enviroment(默认的由AbstractApplicationContext提供),生成StandardServletEnviroment,又例如覆盖ResourcePatternResolver以及对BeanFactory的后处理等。

ConfigurableWebApplicationContext则是web application context的通用接口,为了支持spring-mvc和spring-web定义了一些set方法,例如设置configLocations(ConfigurableApplicationContext接口并不支持setConfigLocation,因为这个接口是跟着ClassPathXmlApplicationContext一起发布的,而web和mvc是后来加上的功能)和nameSpace等。可以把它看成是专门支持web和mvc的一个接口(web和mvc中生成context是通过class.newInstance的无参构造,所以无法将这些信息作为参数传入,必须显示提供set方法以设置属性)

public interface ConfigurableWebApplicationContext extends WebApplicationContext, ConfigurableApplicationContext {

    void setServletContext(ServletContext servletContext);

    void setServletConfig(ServletConfig servletConfig);

    ServletConfig getServletConfig();

    void setNamespace(String namespace);

    String getNamespace();

    void setConfigLocation(String configLocation);

    void setConfigLocations(String... configLocations);

    String[] getConfigLocations();
}

Enviroment实现

再具体说下Enviroment的实现,还是挺有意思的。下图是enviroment的序列图
enviroment

主要说下MutablePropertySources和PropertySource。

最终属性值是通过PropertySource取得,它有多种实现,分别代表一种来源的属性。第二节提到的4种来源则分别对应着ServletConfigPropertySource,ServletContextPropertySource,MapPropertySource和SystemEnvironmentPropertySource。

MutablePropertySources里持有一个property的list,对它迭代直到从一个PropertySource里取出对应key的值就停止,从这可以就看出spring.profiles.active是有先后优先级的。

有兴趣的可以看下源码,会稍微有些繁琐。有一点需要注意:spring web和mvc模块会在refresh applicationContext之前调用相应enviroment#initPropertySources生成ServletConfigPropertySource和ServletContextPropertySource。相应的MapPropertySource和SystemEnvironmentPropertySource则是默认生成的。所以如果不是web项目,就只能通过配置system properties或者env指定activeProfile。

目录
相关文章
|
3天前
|
Cloud Native Java 对象存储
面向未来的架构设计:Spring Cloud和Netflix OSS在云原生环境下的发展趋势
展望未来,随着5G、边缘计算等新技术的兴起,微服务架构的设计理念将会更加深入人心,Spring Cloud和Netflix OSS也将继续引领技术潮流,为企业带来更为高效、灵活且强大的解决方案。无论是对于初创公司还是大型企业而言,掌握这些前沿技术都将是在激烈市场竞争中脱颖而出的关键所在。
13 0
|
3天前
|
Java 对象存储 开发者
解析Spring Cloud与Netflix OSS:微服务架构中的左右手如何协同作战
Spring Cloud与Netflix OSS不仅是现代微服务架构中不可或缺的一部分,它们还通过不断的技术创新和社区贡献推动了整个行业的发展。无论是对于初创企业还是大型组织来说,掌握并合理运用这两套工具,都能极大地提升软件系统的灵活性、可扩展性以及整体性能。随着云计算和容器化技术的进一步普及,Spring Cloud与Netflix OSS将继续引领微服务技术的发展潮流。
13 0
|
2天前
|
存储 Java 数据库
Spring Boot 优雅实现多租户架构
本文详细介绍如何使用Spring Boot和Spring Cloud实现多租户架构。多租户架构允许多个租户共用一个应用,各自拥有独立资源和数据。其优势包括满足个性化需求、降低成本、复用代码以及增强可扩展性。文中探讨了架构选型、数据库设计、应用部署及租户管理等内容,并提供了具体实现步骤和技术细节。适用于SaaS应用和多租户云服务等场景。
|
19天前
|
编解码 人工智能 文件存储
卷积神经网络架构:EfficientNet结构的特点
EfficientNet是一种高效的卷积神经网络架构,它通过系统化的方法来提升模型的性能和效率。
25 1
|
22天前
|
缓存 Java 应用服务中间件
随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架
【9月更文挑战第6天】随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架。Nginx作为高性能的HTTP反向代理服务器,常用于前端负载均衡,提升应用的可用性和响应速度。本文详细介绍如何通过合理配置实现Spring Boot与Nginx的高效协同工作,包括负载均衡策略、静态资源缓存、数据压缩传输及Spring Boot内部优化(如线程池配置、缓存策略等)。通过这些方法,开发者可以显著提升系统的整体性能,打造高性能、高可用的Web应用。
54 2
|
3天前
|
Cloud Native Java 对象存储
揭秘微服务架构之争:Spring Cloud与Netflix OSS巅峰对决,谁将称霸弹性云原生时代?
近年来,微服务架构成为企业应用的主流设计模式。本文对比了两大热门框架Spring Cloud和Netflix OSS,探讨其在构建弹性微服务方面的表现。Spring Cloud依托Spring Boot,提供全面的微服务解决方案,包括服务注册、配置管理和负载均衡等。Netflix OSS则由一系列可独立或组合使用的组件构成,如Eureka、Hystrix等。两者相比,Spring Cloud更易集成且功能完善,而Netflix OSS则需自行整合组件,但灵活性更高。实际上,两者也可结合使用以发挥各自优势。通过对两者的对比分析,希望为企业在微服务架构选型上提供参考。
16 0
|
30天前
|
负载均衡 Java 应用服务中间件
Spring Boot 多活架构背后究竟隐藏着怎样的神秘力量?快来一探究竟!
【8月更文挑战第29天】在数字化时代,企业应用需具备高可用性和可靠性,Spring Boot 作为一种流行 Java 框架,为实现多活架构(Active-Active Architecture)提供了强大支持。多活架构通过在多个数据中心或节点上同时运行应用,确保高可用性、负载均衡及故障恢复。Spring Boot 可与 Nginx、HAProxy 等负载均衡器集成,并利用 Spring Cloud 实现服务发现与注册,确保系统性能及灾难恢复能力。结合数据库复制和分布式缓存技术,多活架构还能保障数据一致性与同步,满足不同业务需求。
28 1
|
28天前
|
消息中间件 Kafka Java
Spring 框架与 Kafka 联姻,竟引发软件世界的革命风暴!事件驱动架构震撼登场!
【8月更文挑战第31天】《Spring 框架与 Kafka 集成:实现事件驱动架构》介绍如何利用 Spring 框架的强大功能与 Kafka 分布式流平台结合,构建灵活且可扩展的事件驱动系统。通过添加 Spring Kafka 依赖并配置 Kafka 连接信息,可以轻松实现消息的生产和消费。文中详细展示了如何设置 `KafkaTemplate`、`ProducerFactory` 和 `ConsumerFactory`,并通过示例代码说明了生产者发送消息及消费者接收消息的具体实现。这一组合为构建高效可靠的分布式应用程序提供了有力支持。
85 0
|
30天前
|
消息中间件 Java RocketMQ
微服务架构师的福音:深度解析Spring Cloud RocketMQ,打造高可靠消息驱动系统的不二之选!
【8月更文挑战第29天】Spring Cloud RocketMQ结合了Spring Cloud生态与RocketMQ消息中间件的优势,简化了RocketMQ在微服务中的集成,使开发者能更专注业务逻辑。通过配置依赖和连接信息,可轻松搭建消息生产和消费流程,支持消息过滤、转换及分布式事务等功能,确保微服务间解耦的同时,提升了系统的稳定性和效率。掌握其应用,有助于构建复杂分布式系统。
37 0