Friday, October 18, 2013

How spring-boot enables actuator by adding jar dependency?


I was reading spring-boot source code, and wondered how it is auto-detecting actuator features just by adding jar dependency.


spring-boot-actuator


"spring-boot-actuator" adds management-endpoints(http) to the spring-boot application just by adding the jar file.

endpoints are metrics, health-check, spring-security auth audit, etc.

please see here for feature details.


To add actuator to your spring-boot application, add this dependencies:


    org.springframework.boot
    spring-boot-starter-actuator


    org.springframework.boot
    spring-boot-starter-web


Mechanism of auto-detecting spring-boot-actuator


So, how spring-boot application detects spring-boot-actuator?

Sample spring-boot application:

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

"org.springframework.boot.SpringApplication" is the starting point for spring-boot application.

Auto-detection Steps

  1. During "SpringApplication#run" method, it creates an application context from the given source classes("@Configuration" annotated classes). In this case "MyApplication" class.
  2. When "MyApplication" class is being processed as a spring's Java-configuration, "@EnableAutoConfiguration" annotation gets interpreted. "@EnableAutoConfiguration" is a spring-boot(autoconfigure) annotation which is handled by "org.springframework.boot.autoconfigure.EnableAutoConfigurationImportSelector". (how spring handles @Enable* annotation is well documented in this blog post.)
  3. In "EnableAutoConfigurationImportSelector", it uses "org.springframework.core.io.support.SpringFactoriesLoader#loadFactoryNames" from spring-core to load configurations whose key is  "org.springframework.boot.autoconfigure.EnableAutoConfiguration".
    This method reads "META-INF/spring.factories" from jar files.(multiple jar files can have "spring.factories" and when they have same key, comma delimited values will be merged.)
    spring-boot-actuator contains "META-INF/spring.factories" file. The value of the file is a comma delimited list of "@Configuration" classes under "org.springframework.boot.actuate.autoconfigure" package, which are actuator bean definition classes.
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration,\
    org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration,\
    org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration,\
    org.springframework.boot.actuate.autoconfigure.ErrorMvcAutoConfiguration,\
    org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration,\
    org.springframework.boot.actuate.autoconfigure.MetricFilterAutoConfiguration,\
    org.springframework.boot.actuate.autoconfigure.MetricRepositoryAutoConfiguration,\
    org.springframework.boot.actuate.autoconfigure.SecurityAutoConfiguration,\
    org.springframework.boot.actuate.autoconfigure.TraceRepositoryAutoConfiguration,\
    org.springframework.boot.actuate.autoconfigure.TraceWebFilterAutoConfiguration
  4. These configuration classes will be imported into the main application-context, so that, spring-boot-actuator beans become available in the application.

Same mechanism is used for "spring-boot-autoconfigure"
Its jar file contains "spring.factories" file.


Writing a Custom Spring-Boot Module


In sum, you can write a spring-boot module which will be auto-detected by spring-boot application based on the presence of the jar file:
  • include "META-INF/spring.factories" file
    • key: "org.springframework.boot.autoconfigure.EnableAutoConfiguration"
    • value: comma delimited path to @Configuration file(s) for your module








No comments: