2016-11-01 59 views
1

我想要做一個自定義的HealthIndicator,取決於應用程序的正常運行時間。Spring Boot Actuator:如何在自定義HealthIndicator內獲得指標的正常運行時間?

@Component 
public class HealthActuator implements HealthIndicator { 

    private final MetricsEndpoint metricsEndpoint; 

    @Autowired 
    public HealthActuator(MetricsEndpoint metricsEndpoint) { 
     this.metricsEndpoint = metricsEndpoint; 
    } 

    @Override 
    public Health health() { 
     long uptime = (Long) metricsEndpoint.invoke().get("uptime"); 
     // logic with uptime 
     return Health.up().build(); 
    } 

} 

但出現錯誤:a circular dependency between 2 beans in the application context

我可以通過對我的端點/執行器/運行狀況的其餘調用獲得運行時間度量。

但也許是有可能以編程方式嗎?

P.S.日誌堆棧跟蹤:

11-01 14:34:09 WARN org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'healthActuator' defined in file [/Users/serge/projects/bb/bb-imapl/target/classes/bb/imapl/config/HealthActuator.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration$$EnhancerBySpringCGLIB$$2bb06d4a]: Constructor threw exception; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'healthActuator': Requested bean is currently in creation: Is there an unresolvable circular reference? 
11-01 14:34:09 WARN org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'healthActuator' defined in file [/Users/serge/projects/bb/bb-imapl/target/classes/bb/imapl/config/HealthActuator.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration$$EnhancerBySpringCGLIB$$2bb06d4a]: Constructor threw exception; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'healthActuator': Requested bean is currently in creation: Is there an unresolvable circular reference? 
11-01 14:34:09 ERROR org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter - 

*************************** 
APPLICATION FAILED TO START 
*************************** 

Description: 

There is a circular dependency between 2 beans in the application context: 
    - healthActuator defined in file [/Users/serge/projects/bb/bb-imapl/target/classes/bb/imapl/config/HealthActuator.class] 
    - org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration 
    - healthActuator 


11-01 14:34:09 ERROR org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter - 
+0

可以顯示完整的堆棧跟蹤? – alexbt

+0

@Alex用完整的堆棧跟蹤編輯帖子。 –

回答

2

EndpointAutoConfigurationHealthIndicator的依賴(這你HealthActuator實現)。

所以你最終得到循環依賴。當兩個bean彼此需要彼此實例化(通過構造函數注入)時會發生這種情況。 您可以通過使用setter注入打破這個惡性循環:

@Component 
public class HealthActuator implements HealthIndicator { 
    private MetricsEndpoint metricsEndpoint; 

    @Autowired 
    private void setMetricsEndpoint(MetricsEndpoint metricsEndpoint) { 
     this.metricsEndpoint = metricsEndpoint; 
    } 

    public HealthActuator() { 
    } 

    @Override 
    public Health health() { 
     long uptime = (Long) metricsEndpoint.invoke().get("uptime"); 
     // logic with uptime 
     return Health.up().build(); 
    } 
} 
2

如果你不喜歡setter注入,它也應該能夠解決這個與@Lazy ...

@Autowired 
public HealthActuator(@Lazy MetricsEndpoint metricsEndpoint) { 
    this.metricsEndpoint = metricsEndpoint; 
} 
+0

它的工作原理,謝謝。 –

相關問題