Spring Cloud - 1 (Spring Cloud Config Client)

预备知识

发布/订阅模式


java.util.Observable是一个发布者

java.util.Observer是订阅者

发布者和订阅者:1:N

发布者和订阅者:N:M

事件/监听模式

java.util.EventObject:事件对象

  *事件对象总是关联着事件源(Source)

java.util.EventListener:事件监听接口

Spring 事件/监听


ApplicationEvent:应用事件

ApplicationListener:应用监听器

Spring Boot 事件/监听器


ConfigFileApplicationListener

管理配置文件,比如:application.properties以及application.yml

application-{proflie}.properties:

profile = dev、test

1. application-{profile}.properties

2. application.properties

Spring Boot 在相对于ClassPath: /META-INF/spring.factories

Java SPI:java.util.ServiceLoader

Spring SPI:

Spring Boot "/META-INF/spring.factories"

# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

如何控制顺序

实现Ordered以及标记@Order

在Spring里面,数值越小,优先级越高。

Spring Cloud 事件/监听器


BootstrapApplicationListener

Spring Cloud "/META-INF/spring.factories"  --spring-cloud-context

# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.cloud.bootstrap.BootstrapApplicationListener,\
org.springframework.cloud.bootstrap.LoggingSystemShutdownListener,\
org.springframework.cloud.context.restart.RestartListener

加载的优先级高于ConfigFileApplicationListener,所以application.properties文件即使定义也配置不到!

原因在于:

BootstrapApplicationListener 第6优先 (最高优先级+5)

ConfigFileApplicationListener 第11优先 (最高优先级+10)

1. 负责加载bootstrap.properties或者bootstrap.yaml

2. 负责初始化Bootstrap ApplicationContextID="bootstrap"

ConfigurableApplicationContext context = builder.run();

Bootstrap是一个根Spring上下文,parent = null

联想 ClassLoader:

ExtClassLoader  <- AppClassLoader <- SystemClassLoader ->BootstrapClassLoader(null)

ConfigurableApplicationContext

标准实现类:AnnotationConfigApplicationContext

Env端点:EnvironmentEndpoint


Environment关联多个带名称的PropertySource

可以参考一下Spring Framework源码:

AbstractRefreshableWebApplicationContext

@Override
    protected void initPropertySources() {
        ConfigurableEnvironment env = getEnvironment();
        if (env instanceof ConfigurableWebEnvironment) {
            ((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, this.servletConfig);
        }
    }

Environment有两种实现方式:

普通类型:StandardEnvironment

Web类型:StandardServletEnvironment

Environment

  AbstractEnvironment

    -StandardEnvironment

Environment关联着一个PropertySources实例

PropertySources关联着多个PropertySource,并且有优先级

Java System#getProperties实现:名称"systemProperties",对应的内容 System.getProperties()

Java System#getenv实现(环境变量):名称"systemEnvironment",对应的内容 System.getEnv()

关于StringBoot优先级顺序,可以参考:https://docs.spring.io/spring-boot/docs/2.0.0.BUILD-SNAPSHOT/reference/htmlsingle/#boot-features-external-config

实现自定义配置


1. 实现PropertySourceLocator

2. 暴露该实现作为了一个Spring Bean

3. 实现PropertySource

public static class MyPropertySourceLocator implements PropertySourceLocator {

	@Override
	public PropertySource<?> locate(Environment environment) {
		Map<String,Object> source = new HashMap<>();
		source.put("server.port", "9090");
		MapPropertySource propertySource = new MapPropertySource("my-property-source", source);
		return propertySource;
	}
	
}

4. 定义并配置 /META-INF/spring.factories:

org.springframework.cloud.bootstrap.BootstrapConfiguration=\

com.cloud.SpringCloudConfigClientApplication.MyPropertySourceLocator

注意事项:

Environment允许出现同名的配置,不过优先级高的胜出。

内部实现:MutablePropertySources关联代码:

List<PropertySource<?>> propertySourceList = new CopyOnWriteArrayList<PropertySource<?>>();

porpertySourceList FIFO,它有顺序

可以通过MutablePropertySources#addFirst提高到最优先,相当于调用:

List#add(0,PropertySource);

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值