先來一張流程圖:
服務器
Spring Cloud Bus 如何觸發 Refresh?
注:配置中內心我是配置的mq發送消息this
RefreshBusEndpoint中加了@Endpoint(
id = "bus-refresh"
)註解,他就會監控這個/actuator/bus-refresh這個路徑code
而後調用到了busRefresh方法,發佈了RefreshRemoteApplicationEvent事件。blog
這個事件發佈過程當中會使用到ApplicationListenerMethodAdapter來處理,部分代碼以下:事件
protected Object doInvoke(Object... args) { Object bean = getTargetBean(); ReflectionUtils.makeAccessible(this.method); try { //反射執行的方法是BusAutoConfiguration#acceptLocal() return this.method.invoke(bean, args); }
public void onApplicationEvent(RefreshRemoteApplicationEvent event) { Set<String> keys = this.contextRefresher.refresh(); log.info("Received remote refresh request. Keys refreshed " + keys); }
public synchronized Set<String> refresh() { Set<String> keys = refreshEnvironment(); ////對應的bean刷新 this.scope.refreshAll(); return keys; }
public synchronized Set<String> refreshEnvironment() { //獲取以前的配置 Map<String, Object> before = extract( this.context.getEnvironment().getPropertySources()); //從新建立一個SpringApplication並獲取新的配置 addConfigFilesToEnvironment(); //比較配置不一樣的key Set<String> keys = changes(before, extract(this.context.getEnvironment().getPropertySources())).keySet(); //發佈配置改變事件 this.context.publishEvent(new EnvironmentChangeEvent(context, keys)); return keys; }
@ManagedOperation public void rebind() { this.errors.clear(); for (String name : this.beans.getBeanNames()) { //初始化bean rebind(name); } }
public void refreshAll() { //銷燬bean super.destroy(); this.context.publishEvent(new RefreshScopeRefreshedEvent()); }