最新消息: 新版网站上线了!!!

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



转载请注明:谷谷点程序 » Spring Cloud Config Client