Spring 框架核心原理

尽管希腊哲学家赫拉克利特(Heraclitus)并不作为一名软件开发人员而闻名,但他似乎深谙此道。他的一句话经常被引用:“唯一不变的就是变化”,这句话抓住了软件开发的真谛。

我们现在开发应用的方式和1年前、5年前、10年前都是不同的,更别提15年前了,当时RodJohnson的图书 Expert One-on-One J2EE Design and Development 介绍了Spring框架的初始形态。当时,最常见的应用形式是基于浏览器的Web应用,后端由关系型数据库作为支撑。尽管这种形式的开发依然有它的价值,Spring也为这种应用提供了良好的支持,但是我们现在感兴趣的还包括如何开发面向的由微服务组成的应用,这些应用会将数据保存到各种类型的数据库中。

另外一个崭新的关注点是反应式编程,它致力于通过非阻塞操作提供更好的扩展性并提升性能。随着软件开发的发展,Spring框架也在不断变化,以解决现代应用开发中的问题,其中就包括微服务和反应式编程。Spring还通过引入Spring Boot简化自己的开发模型

Spring 的核心

任何实际的应用程序都是由很多组件组成的,每个组件负责整个应用功能的一部分,这些组件需要与其他的应用元素进行协调以完成自己的任务。当应用程序运行时,需要以某种方式创建并引入这些组件。

Spring 框架核心原理

Application Context

Spring的核心是提供了一个容器(container),通常称为Spring应用上下文(Spring Application Context),它们会创建和管理应用组件。

Spring 框架核心原理

Spring 框架核心原理

Spring 框架核心原理

这些组件也可以称为bean,会在Spring应用上下文中装配在一起,从而形成一个完整的应用程序。这就像砖块、砂浆、木材、管道和电线组合在一起,形成一栋房子似的。将bean装配在一起的行为是通过一种基于依赖注入(dependency injection,DI)的模式实现的。此时,组件不会再去创建它所依赖的组件并管理它们的生命周期,使用依赖注入的应用依赖于单独的实体(容器)来创建和维护所有的组件,并将其注入到需要它们的bean中。通常,这是通过构造器参数和属性访问方法来实现的。

Spring 框架核心原理

Spring 框架核心原理

Spring 框架核心原理

Spring 框架核心原理

Spring 容器的刷新 refresh() 过程

Spring 框架核心原理

@Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                initMessageSource();

                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }

流程说明:

1、prepareRefresh();

容器刷新前的准备,设置上下文状态,获取属性,验证必要的属性等

2、obtainFreshBeanFactory();

获取新的beanFactory,销毁原有beanFactory、为每个bean生成BeanDefinition

3、prepareBeanFactory(beanFactory);

配置标准的beanFactory,设置ClassLoader,设置SpEL表达式解析器,添加忽略注入的接口,添加bean,添加bean后置处理器

4、postProcessBeanFactory(beanFactory);

模板方法,此时,所有的beanDefinition已经加载,但是还没有实例化。

允许在子类中对beanFactory进行扩展处理。比如添加ware相关接口自动装配设置,添加后置处理器等,是子类扩展prepareBeanFactory(beanFactory)的方法

5、invokeBeanFactoryPostProcessors(beanFactory);

实例化并调用所有注册的beanFactory后置处理器(实现接口BeanFactoryPostProcessor的bean,在beanFactory标准初始化之后执行)。

例如:

PropertyPlaceholderConfigurer(处理占位符)

6、registerBeanPostProcessors(beanFactory);

实例化和注册beanFactory中扩展了BeanPostProcessor的bean。

例如:

AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)

RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)

CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。

7、initMessageSource();

初始化国际化工具类MessageSource

8、initApplicationEventMulticaster();

初始化事件广播器

9、onRefresh();

模板方法,在容器刷新的时候可以自定义逻辑,不同的Spring容器做不同的事情。

10、registerListeners();

注册监听器,广播early application events

11、finishBeanFactoryInitialization(beanFactory);

实例化所有剩余的(非懒加载)单例

比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化。

实例化的过程各种BeanPostProcessor开始起作用。

12、finishRefresh();

refresh做完之后需要做的其他事情。

清除上下文资源缓存(如扫描中的ASM元数据)

初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)。

发布 ContextRefreshedEvent 事件告知对应的 ApplicationListener 进行相应的操作

Spring的环境抽象

Spring的环境抽象是各种配置属性的一站式服务。它抽取了原始的属性,这样需要这些属性的bean就可以从Spring本身中获取了。Spring环境会拉取多个属性源,包括:

JVM系统属性;

操作系统环境变量;

•命令行参数;

•应用属性配置文件。

它会将这些属性聚合到一个源中,通过这个源可以注入到Spring的bean中。图5.1阐述了来自各个属性源的属性是如何流经Spring的环境抽象进入Spring bean的。

Spring 框架核心原理

Spring 为什么能够长盛不衰?

Spring 之所以能够在技术不断更新换代的IT领域长盛不衰,并且引领技术架构发展的潮流,是因为 Spring 不断适应新技术的发展,不断优化和革新,让Java应用的开发更加便利和高效。从XML配置、注解配置,再到Spring Boot的自动化配置,Spring在不断简化,开发人员需要做的额外工作越来越少。

有时候,我也会思考,真正的技术到底是什么,是某一项生僻的 geek 技巧, 还是某个新的API?这都不是最关键的, 因为这些东西都是不稳定的、易变的,想要在新知识层出不穷的领域中不被淘汰,我们更应该去追求一些内在稳定不变的知识,比如技术的基础规范、设计原理等。

Kotlin 开发者社区

Spring 框架核心原理

国内第一Kotlin 开发者社区公众号,主要分享、交流 Kotlin 编程语言、Spring Boot、Android、React.js/Node.js函数式编程、编程思想等相关主题。

越是喧嚣的世界,越需要宁静的思考。

原文 

http://mp.weixin.qq.com/s?__biz=MzA5OTI2MTE3NA==&mid=2658338501&idx=2&sn=43d7455ef4e0b20c305d5970612198e7

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Spring 框架核心原理

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址