EndPoint詳解


EndPoint詳解

EndPoint主要用於暴露一些SpringMvc內部運行的信息,通常是通過SpringMvc的請求地址獲取相關信息。如/health獲取健康檢查信息。

簡單單元測試

@Test
public void testHealth() throws Exception{
  mockMvc.perform(MockMvcRequestBuilders.get("/health").contentType(MediaType.APPLICATION_JSON_UTF8)).andDo(new ResultHandler() {
    @Override
    public void handle(MvcResult result) throws Exception {
      System.out.println(result.getResponse().getContentAsString());
    }
  });
}
//結果
{"status":"UP","discoveryComposite":{"description":"Discovery Client not initialized","status":"UNKNOWN","discoveryClient":{"description":"Discovery Client not initialized","status":"UNKNOWN"}},"diskSpace":{"status":"UP","total":197553815552,"free":46789115904,"threshold":10485760},"refreshScope":{"status":"UP"},"hystrix":{"status":"UP"},"consul":{"status":"UP","services":{"consul":[]},"advertiseAddress":"172.17.0.8","datacenter":"dc1","domain":"consul.","nodeName":"node-client-v-5-1","bindAddress":"0.0.0.0","clientAddress":"0.0.0.0"}}

url映射

HandlerMapping使用EndpointHandlerMapping,重寫了registerHandlerMethod,主要是注冊HandlerMethod時重寫請求路徑。

private String[] getPatterns(Object handler, RequestMappingInfo mapping) {
  String path = getPath(handler);
  String prefix = StringUtils.hasText(this.prefix) ? this.prefix + path : path;
  Set<String> defaultPatterns = mapping.getPatternsCondition().getPatterns();
  if (defaultPatterns.isEmpty()) {
    return new String[] { prefix, prefix + ".json" };
  }
  List<String> patterns = new ArrayList<String>(defaultPatterns);
  for (int i = 0; i < patterns.size(); i++) {
    patterns.set(i, prefix + patterns.get(i));
  }
  return patterns.toArray(new String[patterns.size()]);
}
private String getPath(Object handler) {
  if (handler instanceof String) {
    handler = getApplicationContext().getBean((String) handler);
  }
  if (handler instanceof MvcEndpoint) {
    return ((MvcEndpoint) handler).getPath();
  }
  return "";
}

如果handler時MvcEndpoint類型,則請求路徑調用getPath方法獲取。

健康檢查為例/health

實現
public HealthEndpoint(HealthAggregator healthAggregator,
    Map<String, HealthIndicator> healthIndicators) {
  super("health", false);
  Assert.notNull(healthAggregator, "HealthAggregator must not be null");
  Assert.notNull(healthIndicators, "HealthIndicators must not be null");
  CompositeHealthIndicator healthIndicator = new CompositeHealthIndicator(
      healthAggregator);
  for (Map.Entry<String, HealthIndicator> entry : healthIndicators.entrySet()) {
    healthIndicator.addHealthIndicator(getKey(entry.getKey()), entry.getValue());
  }
  this.healthIndicator = healthIndicator;
}
@Override
	public Health invoke() {
		return this.healthIndicator.health();
	}

最終回調用HealthIndicator的health()方法。而健康檢查的HealthIndicator為CompositeHealthIndicator。其health方法:

@Override
public Health health() {
  Map<String, Health> healths = new LinkedHashMap<String, Health>();
  for (Map.Entry<String, HealthIndicator> entry : this.indicators.entrySet()) {
    healths.put(entry.getKey(), entry.getValue().health());
  }
  return this.healthAggregator.aggregate(healths);
}

所以,HealthIndicator才是最為關鍵的,CompositeHealthIndicator只是將所有的HealthIndicator合並。

自定義健康檢查實現,即實現HealthIndicator。
@Component
public class TestHelthIndicator extends AbstractHealthIndicator {
    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        builder.up().withDetail("test","testHealth");
    }
}
"testHelthIndicator":{"status":"UP","test":"testHealth"},


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM