RefreshScope原理
Nacos订阅应用启动事件注册listener
com.alibaba.cloud.nacos.refresh.NacosContextRefresher#onApplicationEvent
——>
com.alibaba.cloud.nacos.refresh.NacosContextRefresher#registerNacosListenersForApplications
——>
com.alibaba.cloud.nacos.refresh.NacosContextRefresher#registerNacosListener
——>
com.alibaba.nacos.api.config.ConfigService#addListener
Worker发布事件
com.alibaba.nacos.client.config.impl.ClientWorker.ConfigRpcTransportClient#notifyListenConfig
——>
com.alibaba.nacos.client.config.impl.ClientWorker.ConfigRpcTransportClient#startInternal(while -> poll)
——>
com.alibaba.nacos.client.config.impl.ClientWorker.ConfigRpcTransportClient#executeConfigListen
——>
com.alibaba.nacos.client.config.impl.ClientWorker#refreshContentAndCheck(java.lang.String)
——>
com.alibaba.nacos.client.config.impl.CacheData#checkListenerMd5
——>
com.alibaba.nacos.client.config.impl.CacheData#safeNotifyListener
——>
com.alibaba.nacos.api.config.listener.Listener#receiveConfigInfo
org.springframework.cloud.endpoint.event.RefreshEventListener#handle(org.springframework.cloud.endpoint.event.RefreshEvent)
——>
org.springframework.cloud.context.refresh.ContextRefresher#refresh
——>
org.springframework.cloud.context.scope.refresh.RefreshScope#refreshAll
——>
实现自定义类刷新
@Slf4j
@Component
public class MinioConfigChangeListener implements ApplicationListener<RefreshScopeRefreshedEvent>, ApplicationContextAware {
private ApplicationContext applicationContext;
@Resource
private List<MinioTemplate> minioTemplateList;
@Override
public void onApplicationEvent(RefreshScopeRefreshedEvent event) {
MinioProperties minioProperties = applicationContext.getBean(MinioProperties.class);
Map<String, MinioProperties.MinioItem> idToItemMap = minioProperties.getItems().stream().collect(Collectors.toMap(MinioProperties.MinioItem::getId, Function.identity()));
for (MinioTemplate minioTemplate : minioTemplateList) {
MinioProperties.MinioItem minioItem = minioTemplate.minioItem();
String itemId = minioItem.getId();
MinioProperties.MinioItem newItem = idToItemMap.get(itemId);
minioTemplate.setMinioItem(newItem);
MinioClient newClient = MinioClient.builder().endpoint(newItem.getEndpoint()).credentials(newItem.getAccessKey(), newItem.getSecretKey()).region(newItem.getRegion()).build();
minioTemplate.setMinioClient(newClient);
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}