Spring Boot is excellent for setting up application quickly without re-developing any of the boiler plate (infrastructure) code.
In the application's Spring Config class, I added the following things:
The instructions to create Spring Boot application are provided in the spring.io link. The Spring Intializr provides a quick way to create an application. Spring Boot provides ways to integrate with the different frameworks.
One of the key features of the Spring Boot is the spring-actuator which provides production-ready features out of the box. Spring Boot actuator exposes various endpoints which provides information about the running application. The details of the various endpoints are provided in the Spring Boot documentation.
There were several questions that came to my mind which I read more about Spring Boot Actuator.
- What if you have a web application which uses Spring but it is not a Spring Boot application?
- Would you have to implement all the production-ready features such as Health endpoint, Info endpoint, etc. again in your application?
- Do you have to re-invent the wheel which the Spring team has done in the Spring Boot Actuator project?
- Would it not be great that you could create the dependency on the Spring Boot Actuator jar and get all the functionalities from it?
There are several blog posts which seem to suggest that it can be done. I tried following the instructions, but it seems to not work with the version of Spring Boot that I was trying to use ( version 1.2.5 ).
So, I spend sometime debugging and looking at the Spring Boot Actuator code and figure out how I can set up Spring Boot actuator in a non-boot project.
This is what worked for me.
In the application's build.gradle, I added the following dependency
compile('org.springframework.boot:spring-boot-actuator:1.2.5.RELEASE'){
exclude group: 'org.springframework.boot', module:'spring-boot-starter-logging'}
In the application's Spring Config class, I added the following things:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration;
import org.springframework.boot.actuate.endpoint.BeansEndpoint;
import org.springframework.boot.actuate.endpoint.HealthEndpoint;
import org.springframework.boot.actuate.endpoint.InfoEndpoint;
import org.springframework.boot.actuate.endpoint.RequestMappingEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping;
import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;
import org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
@Configuration
@Import(EndpointAutoConfiguration.class)
public class MyAppSpringConfig {
@Bean
@Autowired
//Define the HandlerMapping similar to RequestHandlerMapping to expose the endpoint
public EndpointHandlerMapping endpointHandlerMapping(
Collection<? extends MvcEndpoint> endpoints
){
return new EndpointHandlerMapping(endpoints);
}
@Bean
@Autowired
//define the HealthPoint endpoint
public HealthMvcEndpoint healthMvcEndpoint(HealthEndpoint delegate){
return new HealthMvcEndpoint(delegate, false);
}
@Bean
@Autowired
//define the Info endpoint
public EndpointMvcAdapter infoMvcEndPoint(InfoEndpoint delegate){
return new EndpointMvcAdapter(delegate);
}
@Bean
@Autowired
//define the beans endpoint
public EndpointMvcAdapter beansEndPoint(BeansEndpoint delegate){
return new EndpointMvcAdapter(delegate);
}
@Bean
@Autowired
//define the mappings endpoint
public EndpointMvcAdapter requestMappingEndPoint(
RequestMappingEndpoint delegate
){
return new EndpointMvcAdapter(delegate);
}
}
Voila, you have added the spring actuator to your application.
In case, you want to get rid of additional dependency of spring-boot-autconfigure from your application, you would have to do the following to integrate it.
In the gradle, you would add:
compile('org.springframework.boot:spring-boot-actuator:1.2.5.RELEASE'){
exclude group: 'org.springframework.boot', module:'spring-boot-starter-logging' exclude group: 'org.springframework.boot', module:'spring-boot-autoconfigure'}
Create a Spring Config and import it to your application's Spring Config. In the example below, I have added only health endpoint and beans endpoint for your reference
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.BeansEndpoint;
import org.springframework.boot.actuate.endpoint.HealthEndpoint;
import org.springframework.boot.actuate.endpoint.RequestMappingEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping;
import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;
import org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
import org.springframework.boot.actuate.health.HealthAggregator;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class BootEndpointAutoConfiguration {
private HealthAggregator healthAggregator = new OrderedHealthAggregator();
private Map<String, HealthIndicator> healthIndicators = new HashMap();
@Bean
@Autowired
//Define handler mapping
public EndpointHandlerMapping endpointHandlerMapping(
Collection<? extends MvcEndpoint> endpoints
){
return new EndpointHandlerMapping(endpoints);
}
@Bean
@Autowired
//Define the beans for exposing the mapping
public EndpointMvcAdapter requestMappingEndPoint(RequestMappingEndpoint delegate){
return new EndpointMvcAdapter(delegate);
}
@Bean
@Autowired
//Define the bean to expose the health
public HealthMvcEndpoint healthMvcEndpoint(HealthEndpoint delegate){
return new HealthMvcEndpoint(delegate, false);
}
@Bean
//Define the bean to expose an health point
public HealthEndpoint healthEndpoint() {
return new HealthEndpoint(this.healthAggregator, this.healthIndicators);
}
@Bean
public BeansEndpoint beansEndpoint() {
return new BeansEndpoint();
}
@Configuration
protected static class RequestMappingEndpointConfiguration {
protected RequestMappingEndpointConfiguration() {
}
@Bean
public RequestMappingEndpoint requestMappingEndpoint() {
RequestMappingEndpoint endpoint = new RequestMappingEndpoint();
return endpoint;
}
}
}
Hi,
ReplyDeleteI tried following these steps, but /health always comes back with a 404. Not sure what am i missing. Can you please help me ? I posted my question on stackoverflow also but didn't get any respose. https://stackoverflow.com/questions/44769516/spring-boot-actuator-not-working-with-non-spring-boot-application
I am also getting same 404.
ReplyDeleteI am getting 404 too
ReplyDeleteI am also getting 404
ReplyDelete