设计模式视角看spring boot

前言:

这一篇需要spring boot和设计模式的基础知识,从设计模式的角度先去谈spring boot,再介绍spring boot的启动流程以及环境注入的一些知识。学习过程中发现网上还是有很多坑的,这里尽量统一做下总结。

                                                                                 fig.1 

一,spring boot简介

                                  fig.2

spring boot中设计到的东西其实很繁杂,如果你学会了Java,并且可以用Java做一些简单的工程,知道Java的多线程机制,JVM,关键字等等,说明你对Java SE以及有了基础。而spring是Java EE的范畴,也就是说,使用Spring框架一般可以作为真正商业可用的应用程序开发,而且大多数公司确实也是用spring框架来实现Java的商业性应用开发。

至于Spring全家桶都有哪些需要你自己去了解,因为涉及到的东西真的很多,这里只讲这套spring boot开发框架中最基础的东西。

什么是Spring Boot?

spring Boot设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架集合之前的spring框架,使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。也就是说,我可以只需要非常少的几个配置就可以迅速方便的搭建起来一套web项目或者是构建一个微服务。

我的意见是,和gRPC类似,spring Boot也是一个要学习怎么去用,不要学习如何去改的框架。首先spring boot运行涉及的概念很明确,不过理解也很繁琐。关于bean,IOC,DI,AOP,注解以及POJO一些spring boot框架开发的概念需要吃透并理解,才能在使用的时候更好理解自己的工程,然后去使用。

二,工厂设计模式与spring boot

Spring使用工厂模式可以通过 BeanFactory 或 ApplicationContext 创建 bean 对象。

BeanFactory :延迟注入(使用到某个 bean 的时候才会注入), 相比于ApplicationContext 来说会占用更少的内存,程序启动速度更快。
ApplicationContext :容器启动的时候,不管你用没用到,一次性创建所有 bean 。BeanFactory 仅提供了最基本的依赖注入支持,ApplicationContext 扩展了 BeanFactory ,除了有BeanFactory的功能还有额外更多功能,所以一般开发人员使用ApplicationContext会更多。

什么是上下文?

"context是environment的snapshot."
每一段程序都有很多外部变量。只有像Add这种简单的函数才是没有外部变量的。一旦你的一段程序有了外部变量,这段程序就不完整,不能独立运行。你为了使他们运行,就要给所有的外部变量一个一个写一些值进去。这些值的集合就叫上下文。

Application Context的实现类

ApplicationContext的三个实现类:

ClassPathXmlApplication:把上下文文件当成类路径资源。
FileSystemXmlApplication:从文件系统中的 XML 文件载入上下文定义信息。
XmlWebApplicationContext:从Web系统中的XML文件载入上下文定义信息。

当以上实现类一般不会在你的工程中用到,spring启动的时候会根据实现注入我们所需要的配置来运行我们想要的工程。

三,观察者模式与spring boot

什么是观察者模式?

当一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。用来使用面向对象技术,将这种依赖关系弱化。

观察者模式是一种对象行为型模式。它表示的是一种对象与对象之间具有依赖关系,当一个对象发生改变的时候,这个对象所依赖的对象也会做出反应。Spring 事件驱动模型就是观察者模式很经典的一个应用。Spring 事件驱动模型非常有用,在很多场景都可以解耦我们的代码。比如我们每次添加商品的时候都需要重新更新商品索引,这个时候就可以利用观察者模式来解决这个问题。


Spring事件驱动角色

事件角色

定义一个事件: 实现一个继承自 ApplicationEvent,并且写相应的构造函数;具体spring boot中定义的事件如图


                                                                         fig.3
事件监听者角色

ApplicationListener 充当了事件监听者角色,它是一个接口,里面只定义了一个 onApplicationEvent()方法来处理ApplicationEvent


事件发布者角色
使用事件发布者发布消息:  可以通过 ApplicationEventPublisher 的 publishEvent() 方法发布消息

Spring事件流程总结


在run的情况下携带上下文运行,然后创建不同的listener去监听事件完成应用的初始化,
在run的时候spring创建并帮助应用程序启动,
1.获取创建listener (starting)
2.创建参数。配置environment(envPrepared) 
3.创建applicationContext 
4.初始化上下文(contextPrepared),加载配置(contextLoaded) 
5.更新上下文(Started),启动程序(running)

四,spring boot env环境注入

Spring Boot可以外部化配置,以便可以在不同环境中使用相同的应用程序代码。你可以使用属性文件,YAML文件,环境变量和命令行参数来外部化配置,可以使用@Value批注将属性值直接注入到您的bean中,可以通过Spring的Environment抽象访问,也可以通过@ConfigurationProperties绑定到结构化对象。

Spring Boot使用一个非常特殊的PropertySource顺序,该顺序旨在允许合理地覆盖值。按以下顺序考虑属性:

https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#boot-features-command-line-runner

1.Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
2.@TestPropertySource annotations on your tests.
3.properties attribute on your tests. Available on @SpringBootTest and the test annotations for testing a particular slice of your application.
4.Command line arguments.
5.Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property).
6.ServletConfig init parameters.
7.ServletContext init parameters.
8.JNDI attributes from java:comp/env.
9.Java System properties (System.getProperties()).
10.OS environment variables.
11.A RandomValuePropertySource that has properties only in random.*.
12.Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants).
13.Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants).
14.Application properties outside of your packaged jar (application.properties and YAML variants).
15.Application properties packaged inside your jar (application.properties and YAML variants).
16.@PropertySource annotations on your @Configuration classes.
17.Default properties (specified by setting SpringApplication.setDefaultProperties).
To provide a concrete example, suppose you develop a @Component that uses a name property, as shown in the following 

@TestPropertySource用法:
@TestPropertySource注解用于springboot项目测试的env配置注入,通过可选元素可以覆盖掉test自身读到的配置文件
可选元素主要有两个:
string[] locations  //指定配置的路径
string[] properties //指定配置的属性
properties的优先级大于locations
举例:
@TestPropertySource(properties = "guardian.server.access.token.admin.perm.enabled=true")
.properties//.yaml
@PropertySource

参考:

1. https://www.ibm.com/developerworks/cn/java/j-lo-spring-boot/index.html#listing4
2. http://www.throwable.club/2018/12/16/spring-boot-environment-configuration-spread/
3. https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#boot-features-command-line-runner

猜你喜欢

转载自blog.csdn.net/wannuoge4766/article/details/106040081