添加依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
接口暴露模式
management.contextPath=/actuator
#取消鑒權(quán)模式
management.security.enabled=false
即所有actuator相關(guān)的接口都需要添加/actuator前綴
查看暴露的接口
http://localhost:8080/actuator/mappings
打開網(wǎng)頁后搜索: /actuator/
actuator源碼解析
先看下actuator是如何實現(xiàn)的,以beans為例子
- /beans請求是哪個spring-bean在處理(endpointHandlerMapping)
http://localhost:8080/actuator/mappings
{
[/actuator/beans || /actuator/beans.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}: {
bean: "endpointHandlerMapping",
method: "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()"
}
訪問mappings接口藻懒,可以看到 /beans的處理類是endpointHandlerMapping
- endpointHandlerMapping對應(yīng)的類是哪個
http://localhost:8080/actuator/beans
{
bean: "endpointHandlerMapping",
aliases: [ ],
scope: "singleton",
type: "org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping",
resource: "class path resource [org/springframework/boot/actuate/autoconfigure/EndpointWebMvcManagementContextConfiguration.class]",
dependencies: [
"mvcEndpoints"
]
}
endpointHandlerMapping對應(yīng)的類為org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping,初始化的configuration類為org/springframework/boot/actuate/autoconfigure/EndpointWebMvcManagementContextConfiguration.class。
- EndpointWebMvcManagementContextConfiguration的初始化過程
@Bean
@ConditionalOnMissingBean
public EndpointHandlerMapping endpointHandlerMapping() {
Set<MvcEndpoint> endpoints = mvcEndpoints().getEndpoints();
CorsConfiguration corsConfiguration = getCorsConfiguration(this.corsProperties);
EndpointHandlerMapping mapping = new EndpointHandlerMapping(endpoints,
corsConfiguration);
mapping.setPrefix(this.managementServerProperties.getContextPath());
MvcEndpointSecurityInterceptor securityInterceptor = new MvcEndpointSecurityInterceptor(
this.managementServerProperties.getSecurity().isEnabled(),
this.managementServerProperties.getSecurity().getRoles());
mapping.setSecurityInterceptor(securityInterceptor);
for (EndpointHandlerMappingCustomizer customizer : this.mappingCustomizers) {
customizer.customize(mapping);
}
return mapping;
}
@Bean
@ConditionalOnMissingBean
public MvcEndpoints mvcEndpoints() {
return new MvcEndpoints();
}
EndpointHandlerMapping的父類為RequestMappingHandlerMapping,RequestMappingHandlerMapping為springmvc的核心類,主要作用是轉(zhuǎn)發(fā)請求到某個具體的方法蕉拢。
MvcEndpoints神奇的地方在于其初始化代碼:
public void afterPropertiesSet() throws Exception {
Collection<MvcEndpoint> existing = BeanFactoryUtils
.beansOfTypeIncludingAncestors(this.applicationContext, MvcEndpoint.class)
.values();
this.endpoints.addAll(existing);
this.customTypes = findEndpointClasses(existing);
@SuppressWarnings("rawtypes")
Collection<Endpoint> delegates = BeanFactoryUtils
.beansOfTypeIncludingAncestors(this.applicationContext, Endpoint.class)
.values();
for (Endpoint<?> endpoint : delegates) {
if (isGenericEndpoint(endpoint.getClass()) && endpoint.isEnabled()) {
EndpointMvcAdapter adapter = new EndpointMvcAdapter(endpoint);
String path = determinePath(endpoint,
this.applicationContext.getEnvironment());
if (path != null) {
adapter.setPath(path);
}
this.endpoints.add(adapter);
}
}
}
主要做了兩件事:
1.查找spring的beanfactory中所有的MvcEndpoint類
2.查找spring的beanfactory中所有的Endpoint類
3.如果某個MvcEndpoint的getEndpointType方法的返回結(jié)果和某個Endpoint的class相沖突,則選取MvcEndpoint
4.查找選取的結(jié)果放在MvcEndpoints的endpoints方法中。
請注意MvcEndpoints和MvcEndpoint和Endpoint區(qū)別扩灯。
- Endpoint是actuator的基本元素媚赖,一個Endpoint代表一個接口
- Endpoint可以單獨使用,單獨使用時MvcEndpoints會使用EndpointMvcAdapter自動將Endpoint封裝為MvcEndpoint對象
- 可以自己主動將Endpoint封裝為MvcEndpoint
- MvcEndpoint可以單獨使用
- MvcEndpoints的作用是將Endpoint和MvcEndpoint整合提供給EndpointHandlerMapping使用
自定義Endpoint
@Bean
public Endpoint<String> testEndPoint(){
return new Endpoint<String>() {
@Override
public String getId() {
return "test";
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public boolean isSensitive() {
return false;
}
@Override
public String invoke() {
return "invokeingTestEndPoint";
}
};
}
getId方法是path珠插,這個path為:/actuator/test
自定義MvcEndpoint
@Bean
public MvcEndpoint testMvcEndpoint(){
return new MvcEndpoint() {
@Override
public String getPath() {
return "/testMvcEndpoint";
}
@Override
public boolean isSensitive() {
return false;
}
@RequestMapping("testMvcEndpoint")
@ResponseBody
public String get(){
return "invokingTestMvcEndpoint";
}
@RequestMapping("testMvcEndpoint2")
@ResponseBody
public String ge2t(){
return "invokingTestMvcEndpoint2";
}
@Override
public Class<? extends Endpoint> getEndpointType() {
return null;
}
};
}
getPath()方法為path前綴惧磺,類似于controller類上的RequestMapping,實際的path需要拼接上各個方法定義的RequestMapping捻撑。
這個bean定義了兩個path:
- /actuator/testMvcEndpoint/testMvcEndpoint
- /actuator/testMvcEndpoint/testMvcEndpoint2