@@ -23,7 +23,32 @@ SpringCloud 是在 SpringBoot 的基础上构建的。Spring Cloud 以两个库
2323
2424[ 前置知识:SprinBoot 加载 application.yml 的原理] ( https://github.com/haitaoss/spring-boot/blob/source-v2.7.8/note/springboot-source-note.md#%E5%B1%9E%E6%80%A7%E6%96%87%E4%BB%B6%E7%9A%84%E5%8A%A0%E8%BD%BD%E9%A1%BA%E5%BA%8F )
2525
26- [ 示例代码] ( https://github.com/haitaoss/spring-cloud-commons/tree/source-v3.1.5/source-note-spring-cloud-commons/src/main/java/cn/haitaoss/BootstrapProperties/Main.java )
26+ 示例代码
27+
28+ ``` java
29+ @EnableAutoConfiguration
30+ public class Main {
31+
32+ public static void main (String [] args ) {
33+ // 是否创建 bootstrapContext
34+ System . setProperty(" spring.cloud.bootstrap.enabled" , " true" );
35+ // 设置 bootstrapContext 中属性文件的搜索目录 或者是 属性文件
36+ System . setProperty(" spring.cloud.bootstrap.location" , " " );
37+ System . setProperty(" spring.cloud.bootstrap.additional-location" ,
38+ " optional:classpath:/config/haitao/,classpath:/haitao.properties" );
39+ // 设置 bootstrapContext 默认属性文件的名字
40+ // System.setProperty("spring.cloud.bootstrap.name", "bootstrap-haitao");
41+ // 设置 profile
42+ // System.setProperty("spring.profiles.active", "haitao");
43+ // 测试读取属性
44+ ConfigurableApplicationContext context = SpringApplication . run(Main . class, args);
45+ ConfigurableEnvironment environment = context. getEnvironment();
46+ Stream . iterate(1 , i - > i + 1 ). limit(5 ). map(i - > " p" + i). forEach(
47+ name - > System . out. println(String . format(" key:%s \t valus: %s" , name, environment. getProperty(name))));
48+ }
49+
50+ }
51+ ```
2752
2853BootstrapApplicationListener 是用于完成 SpringCloud 的接入的,主要是完成 bootstrapContext 的创建、bootstrap 属性的加载、设置 bootstrapContext 为父容器。下面是 BootstrapApplicationListener 被触发的入口和核心逻辑
2954
@@ -109,7 +134,43 @@ public class BootstrapImportSelectorConfiguration {}
109134
110135### PropertySourceBootstrapConfiguration
111136
112- [ 示例代码] ( https://github.com/haitaoss/spring-cloud-commons/tree/source-v3.1.5/source-note-spring-cloud-commons/src/main/java/cn/haitaoss/BootstrapProperties/BootstrapConfiguration/MyPropertySourceLocator.java )
137+ 示例代码
138+
139+ ``` java
140+ public class MyPropertySourceLocator implements PropertySourceLocator {
141+
142+ public MyPropertySourceLocator () {
143+ System . out. println(" MyPropertySourceLocator...构造器" );
144+ }
145+
146+ @Resource
147+ private ApplicationContext applicationContext;
148+
149+ @Value (" ${dynamicConfigFile}" )
150+ private String filePath;
151+
152+ @Override
153+ public PropertySource<?> locate (Environment environment ) {
154+ PropertySource<?> propertySource;
155+ try {
156+ // 也可以改成网络资源
157+ propertySource = new YamlPropertySourceLoader ()
158+ .load(" haitao-propertySource" , applicationContext. getResource(filePath)). get(0 );
159+ } catch (IOException e) {
160+ throw new RuntimeException (e);
161+ }
162+ return propertySource;
163+ }
164+
165+ }
166+ ```
167+
168+ ` META-INF/spring.factories `
169+
170+ ``` properties
171+ org.springframework.cloud.bootstrap.BootstrapConfiguration =\
172+ cn.haitaoss.BootstrapProperties.BootstrapConfiguration.MyPropertySourceLocator
173+ ```
113174
114175``` java
115176/**
@@ -154,7 +215,39 @@ public class BootstrapImportSelectorConfiguration {}
154215
155216## @RefreshScope 和 @ConfigurationProperties bean 的更新
156217
157- [ 示例代码] ( https://github.com/haitaoss/spring-cloud-commons/tree/source-v3.1.5/source-note-spring-cloud-commons/src/main/java/cn/haitaoss/refresh/Main.java )
218+ 示例代码
219+
220+ ``` java
221+ @SpringBootApplication
222+ public class Main {
223+
224+ /**
225+ * 总结用法:
226+ *
227+ * 可以通过属性 spring.cloud.refresh.refreshable spring.cloud.refresh.extraRefreshable
228+ * 代替 @RefreshScope
229+ *
230+ * 可以设置属性 spring.cloud.refresh.enabled=false 取消 @RefreshScope 的自动注入 是
231+ * spring.cloud.refresh.never-refreshable 属性记录的类就不重会新绑定属性
232+ */
233+ public static void main (String [] args ) {
234+ // TODOHAITAO: 2023/4/6 访问验证属性更新 GET http://127.0.0.1:8080/actuator/refresh
235+ // 启用 bootstrap 属性的加载
236+ System . setProperty(" spring.cloud.bootstrap.enabled" , " true" );
237+
238+ // 通过配置属性的方式,扩展bean为 refresh scope 的
239+ System . setProperty(" spring.cloud.refresh.refreshable" ,
240+ Arrays . asList(RefreshScopeBean1 . class. getName(), RefreshScopeBean2 . class. getName()). stream()
241+ .collect(Collectors . joining(" ," )));
242+ System . setProperty(" spring.cloud.refresh.extraRefreshable" ,
243+ Arrays . asList(Object . class. getName()). stream(). collect(Collectors . joining(" ," )));
244+
245+ // 设置 bootstrapContext 会默认加载的 bean
246+ System . setProperty(" spring.cloud.bootstrap.sources" ," cn.haitaoss.RefreshScope.config.MyPropertySourceLocator" );
247+ }
248+
249+ }
250+ ```
158251
159252``` java
160253/**
@@ -438,7 +531,29 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
438531
439532## LoadBalancerClient
440533
441- [ 示例代码] ( https://github.com/haitaoss/spring-cloud-commons/tree/source-v3.1.5/source-note-spring-cloud-commons/src/main/java/cn/haitaoss/ServiceRegisterAndLoadBalance/Main.java )
534+ 示例代码
535+
536+ ``` java
537+ @EnableAutoConfiguration
538+ @RestController
539+ @Import ({ LoadBalancerClientConfig . class, LoadBalancerOtherConfig . class })
540+ public class Main extends BaseApp {
541+
542+ public static void main (String [] args ) {
543+ /**
544+ * TODOHAITAO: 2023/4/7 验证方式 运行 Main、Client1、Client2 然后访问:
545+ * - 堵塞式 GET http://localhost:8080/s1
546+ * - 响应式 GET http://localhost:8080/2/s1
547+ */
548+ // 采用那种方式对 RestTemplate 进行增强,看
549+ // org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration
550+ System . setProperty(" spring.cloud.loadbalancer.retry.enabled" , " false" );
551+ System . setProperty(" spring.profiles.active" , " loadbalance" );
552+ ConfigurableApplicationContext context = SpringApplication . run(Main . class);
553+ }
554+
555+ }
556+ ```
442557
443558负载均衡会使用 LoadBalancerClient 来执行请求的,大致逻辑是通过 DiscoveryClient 得到 serviceId 有哪些实例,再通过负载均衡策略的逻辑筛选出唯一的实例,然后根据这个实例的 url 执行请求。
444559
@@ -720,7 +835,16 @@ spring.cloud.loadbalancer.retry.backoff.jitter=1
720835
721836### ReactorLoadBalancer
722837
723- [ 示例代码] ( https://github.com/haitaoss/spring-cloud-commons/tree/source-v3.1.5/source-note-spring-cloud-commons/src/main/java/cn/haitaoss/ServiceRegisterAndLoadBalance/loadbalancer/LoadBalancerClientConfig.java )
838+ 示例代码
839+
840+ ``` java
841+ @LoadBalancerClient (name = " s1" , configuration = { MyLoadBalancer . class, MyServiceInstanceListSupplier . class })
842+ @LoadBalancerClients ({ @LoadBalancerClient (name = " s2" , configuration = MyRandomLoadBalancer . class),
843+ @LoadBalancerClient (name = " s3" , configuration = MyRoundRobinLoadBalancer . class), })
844+ public class LoadBalancerClientConfig {
845+
846+ }
847+ ```
724848
725849``` java
726850/**
@@ -783,7 +907,28 @@ public class LoadBalancerClientConfiguration {
783907
784908### ServiceInstanceListSupplier
785909
786- [ 示例代码] ( https://github.com/haitaoss/spring-cloud-commons/tree/source-v3.1.5/source-note-spring-cloud-commons/src/main/java/cn/haitaoss/ServiceRegisterAndLoadBalance/loadbalancer/MyServiceInstanceListSupplier.java )
910+ 示例代码
911+
912+ ``` java
913+ public class MyServiceInstanceListSupplier {
914+
915+ @Bean
916+ public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier (
917+ ConfigurableApplicationContext context ) {
918+ return ServiceInstanceListSupplier . builder()
919+ // .withDiscoveryClient() // 通过 ReactiveDiscoveryClient 获取 List<ServiceInstance>
920+ .withBlockingDiscoveryClient() // 通过 DiscoveryClient 获取 List<ServiceInstance>
921+ // 下面配置的是通过什么方式 过滤 List<ServiceInstance>
922+ // .withZonePreference() // spring.cloud.loadbalancer.zone" 属性值与 serviceInstance.getMetadata().get("zone") 进行匹配
923+ // .withBlockingHealthChecks() // spring.cloud.loadbalancer.healthCheck.* 属性定义的的规则来过滤
924+ // .withRequestBasedStickySession() spring.cloud.loadbalancer.stickySession.instanceIdCookieName 属性值过滤 serviceInstance.getInstanceId()
925+ // .withSameInstancePreference()
926+ .withCaching() // 会使用到 LoadBalancerCacheManager 缓存 List<ServiceInstance>
927+ .build(context);
928+ }
929+
930+ }
931+ ```
787932
788933``` java
789934/**
@@ -803,15 +948,15 @@ public class LoadBalancerClientConfiguration {
803948``` java
804949public interface ServiceInstanceListSupplier extends Supplier<Flux<List<ServiceInstance > > > {
805950
806- String getServiceId ();
951+ String getServiceId ();
807952
808- default Flux<List<ServiceInstance > > get (Request request ) {
809- return get();
810- }
953+ default Flux<List<ServiceInstance > > get (Request request ) {
954+ return get();
955+ }
811956
812- static ServiceInstanceListSupplierBuilder builder () {
813- return new ServiceInstanceListSupplierBuilder ();
814- }
957+ static ServiceInstanceListSupplierBuilder builder () {
958+ return new ServiceInstanceListSupplierBuilder ();
959+ }
815960
816961}
817962```
@@ -820,8 +965,6 @@ public interface ServiceInstanceListSupplier extends Supplier<Flux<List<ServiceI
820965
821966WebClient.Builder 是执行响应式请求的工具类。下面是让 WebClient.Builder 具有负载均衡能力的实现逻辑。
822967
823- [ 示例代码] ( https://github.com/haitaoss/spring-cloud-commons/tree/source-v3.1.5/source-note-spring-cloud-commons/src/main/java/cn/haitaoss/ServiceRegisterAndLoadBalance/loadbalancer/LoadBalancerOtherConfig.java )
824-
825968` spring-cloud-commons.jar!/META-INF/spring.factories ` 的部分内容
826969
827970``` properties
0 commit comments