or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

conditional-annotations.mdcore-infrastructure.mdendpoint-filtering.mdendpoint-properties.mdindex.mdjmx-endpoints.mdmanagement-endpoints.mdmanagement-server.mdweb-endpoints.md
tile.json

tessl/maven-org-springframework-boot--spring-boot-actuator-autoconfigure

Spring Boot Actuator AutoConfigure module providing production-ready features to Spring Boot applications through auto-configuration

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/org.springframework.boot/spring-boot-actuator-autoconfigure@4.0.x

To install, run

npx @tessl/cli install tessl/maven-org-springframework-boot--spring-boot-actuator-autoconfigure@4.0.0

index.mddocs/

Spring Boot Actuator AutoConfigure

Spring Boot Actuator AutoConfigure provides automatic configuration for Spring Boot Actuator, enabling production-ready monitoring and management features. It auto-configures actuator endpoints based on classpath dependencies and application properties, following Spring Boot's convention-over-configuration philosophy. This module handles endpoint discovery, filtering, exposure (via HTTP and JMX), and management server configuration.

Quick Reference

Essential Maven Dependency

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Most Common Properties (Copy-Paste Ready)

# Expose all web endpoints
management.endpoints.web.exposure.include=*

# Expose specific endpoints
management.endpoints.web.exposure.include=health,info,metrics

# Change base path
management.endpoints.web.base-path=/actuator

# Separate management port
management.server.port=8081

# Endpoint access control
management.endpoint.health.show-details=always
management.endpoint.env.show-values=NEVER

Core Imports

// Endpoint annotations
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector;

// Conditional annotations
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType;

// Core infrastructure
import org.springframework.boot.actuate.endpoint.EndpointAccessResolver;
import org.springframework.boot.actuate.endpoint.Access;
import org.springframework.boot.actuate.endpoint.EndpointId;

// Properties
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties;

Package Information

  • Package Name: spring-boot-actuator-autoconfigure
  • Package Type: Maven
  • Group ID: org.springframework.boot
  • Artifact ID: spring-boot-actuator-autoconfigure
  • Version: 4.0.0
  • Language: Java

Decision Matrices

When to Use Separate Management Port

ScenarioSame PortSeparate PortReason
Simple applicationLess complexity
Production with network isolation neededCan restrict management access
Docker/KubernetesLiveness/readiness on main port
Internal monitoring toolsSeparate security policies
High-security requirementsFirewall rules isolation

Endpoint Exposure Strategy

EnvironmentWeb ExposureJMX ExposureRationale
Development**Full visibility for debugging
Staginghealth,info,metrics,loggers*Limited web, full internal
Productionhealth,info,metrics,prometheushealth,metricsMinimal exposure

Show-Values Configuration

EnvironmentconfigpropsenvRationale
DevelopmentALWAYSALWAYSFull visibility
StagingWHEN_AUTHORIZEDWHEN_AUTHORIZEDRole-based access
ProductionNEVERNEVERMaximum security

Common Patterns

Pattern 1: Custom Endpoint (Minimal)

@Component
@Endpoint(id = "custom")
public class CustomEndpoint {

    @ReadOperation
    public Map<String, Object> getData() {
        return Map.of("status", "ok", "timestamp", System.currentTimeMillis());
    }
}

Property required: management.endpoints.web.exposure.include=custom

Pattern 2: Custom Endpoint with Auto-Configuration

// Endpoint class
@Endpoint(id = "custom")
public class CustomEndpoint {
    @ReadOperation
    public Map<String, Object> getData() {
        return Map.of("status", "ok");
    }
}

// Auto-configuration
@AutoConfiguration
@ConditionalOnAvailableEndpoint(endpoint = CustomEndpoint.class)
public class CustomEndpointAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean
    public CustomEndpoint customEndpoint() {
        return new CustomEndpoint();
    }
}

Pattern 3: Custom Info Contributor

@Component
public class CustomInfoContributor implements InfoContributor {
    @Override
    public void contribute(Info.Builder builder) {
        builder.withDetail("custom", Map.of("key", "value"));
    }
}

Property required: management.info.custom.enabled=true

Pattern 4: Endpoint with Selector (Path Variables)

@Endpoint(id = "cache")
public class CacheEndpoint {

    @ReadOperation
    public Map<String, Object> getCache(@Selector String cacheName) {
        // GET /actuator/cache/{cacheName}
        return cacheManager.getCache(cacheName).asMap();
    }

    @DeleteOperation
    public void evictCache(@Selector String cacheName) {
        // DELETE /actuator/cache/{cacheName}
        cacheManager.getCache(cacheName).clear();
    }
}

Pattern 5: Management Context Configuration

// Register in META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports
@ManagementContextConfiguration(ManagementContextType.CHILD)
public class CustomManagementConfiguration {
    @Bean
    public CustomManagementBean customBean() {
        return new CustomManagementBean();
    }
}

Architecture Overview

┌─────────────────────────────────────────────────────────┐
│           Endpoint Auto-Configuration Layer             │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐ │
│  │   Endpoint   │  │   Endpoint   │  │  Endpoint    │ │
│  │ Discovery    │→ │  Filtering   │→ │  Exposure    │ │
│  └──────────────┘  └──────────────┘  └──────────────┘ │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│              Exposure Technology Layer                   │
│  ┌──────────────────┐         ┌───────────────────┐    │
│  │  Web Endpoints   │         │  JMX Endpoints    │    │
│  │  (HTTP/JSON)     │         │  (MBeans)         │    │
│  └──────────────────┘         └───────────────────┘    │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│               Server Infrastructure Layer                │
│  ┌──────────────────┐         ┌───────────────────┐    │
│  │  Same Server     │   OR    │  Separate Server  │    │
│  │  (server.port)   │         │  (mgmt.port)      │    │
│  └──────────────────┘         └───────────────────┘    │
└─────────────────────────────────────────────────────────┘

Subsystems Reference

SubsystemDocumentationKey ClassesPrimary Use
Core Infrastructurecore-infrastructure.mdEndpointAutoConfiguration, PropertiesEndpointAccessResolverEndpoint parameter mapping, caching, access control
Management Endpointsmanagement-endpoints.mdBeansEndpoint, HealthEndpoint, InfoEndpoint, etc.Individual endpoint implementations
Web Exposureweb-endpoints.mdWebEndpointAutoConfiguration, WebEndpointPropertiesHTTP endpoint exposure, CORS, path mapping
JMX Exposurejmx-endpoints.mdJmxEndpointAutoConfiguration, JmxEndpointPropertiesJMX MBean endpoint exposure
Endpoint Propertiesendpoint-properties.mdConfigurationPropertiesReportEndpointProperties, EnvironmentEndpointPropertiesEndpoint-specific configuration
Endpoint Filteringendpoint-filtering.mdIncludeExcludeEndpointFilter, EndpointExposureInclude/exclude pattern filtering
Management Servermanagement-server.mdManagementServerProperties, ManagementPortTypeSeparate management port configuration
Conditional Annotationsconditional-annotations.md@ConditionalOnAvailableEndpoint, @ConditionalOnManagementPortConditional component registration

Available Endpoints Quick Reference

Endpoint IDPathHTTP MethodsDefault ExposedPurposeAuto-Config Class
health/actuator/healthGETYes (web, jmx)Application health status(In spring-boot-health module)
info/actuator/infoGETYes (web)Application informationInfoEndpointAutoConfiguration
metrics/actuator/metricsGETNoApplication metrics(In spring-boot-actuator-metrics module)
beans/actuator/beansGETNoAll Spring beansBeansEndpointAutoConfiguration
conditions/actuator/conditionsGETNoAuto-configuration reportConditionsReportEndpointAutoConfiguration
configprops/actuator/configpropsGETNoConfiguration propertiesConfigurationPropertiesReportEndpointAutoConfiguration
env/actuator/envGETNoEnvironment propertiesEnvironmentEndpointAutoConfiguration
loggers/actuator/loggersGET, POSTNoLogger levels (mutable)LoggersEndpointAutoConfiguration
heapdump/actuator/heapdumpGETNoDownload heap dumpHeapDumpWebEndpointAutoConfiguration
threaddump/actuator/threaddumpGETNoThread dumpThreadDumpEndpointAutoConfiguration
shutdown/actuator/shutdownPOSTNoGraceful shutdownShutdownEndpointAutoConfiguration
mappings/actuator/mappingsGETNoRequest mappingsMappingsEndpointAutoConfiguration
scheduledtasks/actuator/scheduledtasksGETNoScheduled tasksScheduledTasksEndpointAutoConfiguration
httpexchanges/actuator/httpexchangesGETNoHTTP request/response logHttpExchangesEndpointAutoConfiguration
auditevents/actuator/auditeventsGETNoSecurity audit eventsAuditEventsEndpointAutoConfiguration
sbom/actuator/sbomGETNoSoftware Bill of MaterialsSbomEndpointAutoConfiguration
startup/actuator/startupGETNoApplication startup infoStartupEndpointAutoConfiguration
logfile/actuator/logfileGETNoDownload log fileLogFileWebEndpointAutoConfiguration

Key Configuration Properties Reference

Endpoint Exposure

# Default: health (both web and jmx)
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=shutdown
management.endpoints.jmx.exposure.include=*
management.endpoints.jmx.exposure.exclude=

# Base paths
management.endpoints.web.base-path=/actuator
management.server.base-path=

Endpoint Access Control

# Access levels: UNRESTRICTED, READ_ONLY, NONE
management.endpoints.access.default=READ_ONLY
management.endpoints.access.max-permitted=UNRESTRICTED
management.endpoint.<id>.access=UNRESTRICTED

Management Server

# Port configuration
management.server.port=8081          # Separate port
management.server.port=-1            # Disable management
# (not set = same as server.port)

management.server.address=127.0.0.1  # Bind address
management.server.base-path=/admin   # Additional base path

Endpoint-Specific

# Health
management.endpoint.health.show-details=always|never|when-authorized

# Environment & ConfigProps
management.endpoint.env.show-values=NEVER|ALWAYS|WHEN_AUTHORIZED
management.endpoint.env.roles=ADMIN
management.endpoint.configprops.show-values=NEVER|ALWAYS|WHEN_AUTHORIZED
management.endpoint.configprops.roles=ADMIN

# Info Contributors
management.info.git.enabled=true
management.info.git.mode=SIMPLE|FULL
management.info.env.enabled=true
management.info.java.enabled=true
management.info.defaults.enabled=true

# HTTP Exchanges
management.httpexchanges.recording.include=TIME_TAKEN,REQUEST_HEADERS,RESPONSE_HEADERS

# Caching
management.endpoint.<id>.cache.time-to-live=10s

CORS

management.endpoints.web.cors.allowed-origins=https://example.com
management.endpoints.web.cors.allowed-methods=GET,POST
management.endpoints.web.cors.allowed-headers=*
management.endpoints.web.cors.allow-credentials=true
management.endpoints.web.cors.max-age=3600

Capabilities

Core Endpoint Infrastructure

Core infrastructure for endpoint discovery, filtering, parameter mapping, caching, and access control.

@AutoConfiguration
public final class EndpointAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean
    ParameterValueMapper endpointOperationParameterMapper(
        @EndpointConverter ObjectProvider<Converter<?, ?>> converters,
        @EndpointConverter ObjectProvider<GenericConverter> genericConverters
    );

    @Bean
    @ConditionalOnMissingBean
    CachingOperationInvokerAdvisor endpointCachingOperationInvokerAdvisor(Environment environment);

    @Bean
    @ConditionalOnMissingBean(EndpointAccessResolver.class)
    PropertiesEndpointAccessResolver propertiesEndpointAccessResolver(Environment environment);
}

public class PropertiesEndpointAccessResolver implements EndpointAccessResolver {
    public Access accessFor(EndpointId endpointId, Access defaultAccess);
}

Core Endpoint Infrastructure

Endpoint JSON Serialization

Configures JSON serialization for endpoint responses using Jackson.

/**
 * Auto-configuration for endpoint JSON serialization (Jackson 3)
 */
@AutoConfiguration
@ConditionalOnClass(JsonMapper.class)
public final class JacksonEndpointAutoConfiguration {

    /**
     * Provides isolated JSON mapper for endpoint serialization
     * Uses separate ObjectMapper instance to avoid conflicts with application JSON configuration
     */
    @Bean
    @ConditionalOnBooleanProperty(name = "management.endpoints.jackson.isolated-json-mapper", matchIfMissing = true)
    EndpointJsonMapper endpointJsonMapper();
}

/**
 * Auto-configuration for endpoint JSON serialization (Jackson 2 - DEPRECATED)
 * @deprecated since 4.0.0, scheduled for removal in 4.2.0
 * Use JacksonEndpointAutoConfiguration instead (Jackson 3)
 */
@Deprecated(since = "4.0.0", forRemoval = true)
@SuppressWarnings("removal")
@AutoConfiguration
@ConditionalOnClass({ ObjectMapper.class, Jackson2ObjectMapperBuilder.class })
public final class Jackson2EndpointAutoConfiguration {

    /**
     * Provides Jackson 2 based JSON mapper for endpoints
     * @deprecated Use JacksonEndpointAutoConfiguration instead
     */
    @Bean
    @Deprecated(since = "4.0.0", forRemoval = true)
    EndpointJackson2ObjectMapper jackson2EndpointJsonMapper();
}

Properties:

# Jackson 3 - Enable/disable isolated JSON mapper (default: true)
management.endpoints.jackson.isolated-json-mapper=true

# Jackson 2 (deprecated) - Enable/disable isolated object mapper (default: true)
management.endpoints.jackson2.isolated-object-mapper=true

Key Features:

  • Isolated JSON Mapper: Uses separate ObjectMapper instance to avoid conflicts with application JSON configuration
  • Jackson 3 Support: Primary configuration using Jackson 3 (JsonMapper)
  • Jackson 2 Support (Deprecated): Legacy support for Jackson 2, scheduled for removal in 4.2.0

Migration Note: Applications using Jackson 2 should migrate to Jackson 3. Jackson2EndpointAutoConfiguration is deprecated since 4.0.0 and will be removed in 4.2.0.

Web Endpoint Exposure

Configures HTTP exposure of actuator endpoints, including path mapping, filtering, and CORS.

@AutoConfiguration
@ConditionalOnWebApplication
public final class WebEndpointAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean(WebEndpointsSupplier.class)
    WebEndpointDiscoverer webEndpointDiscoverer(
        ParameterValueMapper parameterValueMapper,
        EndpointMediaTypes endpointMediaTypes,
        ObjectProvider<PathMapper> endpointPathMappers,
        ObjectProvider<AdditionalPathsMapper> additionalPathsMappers,
        ObjectProvider<OperationInvokerAdvisor> invokerAdvisors,
        ObjectProvider<EndpointFilter<ExposableWebEndpoint>> endpointFilters,
        ObjectProvider<OperationFilter<WebOperation>> operationFilters
    );

    @Bean
    PathMapper webEndpointPathMapper();

    @Bean
    PathMappedEndpoints pathMappedEndpoints(
        Collection<EndpointsSupplier<?>> endpointSuppliers
    );
}

@ConfigurationProperties("management.endpoints.web")
public class WebEndpointProperties {
    private String basePath = "/actuator";
    private Map<String, String> pathMapping = new LinkedHashMap<>();
    private Exposure exposure = new Exposure();
    private Discovery discovery = new Discovery();

    public static class Exposure {
        private Set<String> include = new LinkedHashSet<>();
        private Set<String> exclude = new LinkedHashSet<>();
    }
}

@ConfigurationProperties("management.endpoints.web.cors")
public class CorsEndpointProperties {
    private List<String> allowedOrigins = new ArrayList<>();
    private List<String> allowedOriginPatterns = new ArrayList<>();
    private List<String> allowedMethods = new ArrayList<>();
    private List<String> allowedHeaders = new ArrayList<>();
    private List<String> exposedHeaders = new ArrayList<>();
    private Boolean allowCredentials;
    private Duration maxAge = Duration.ofSeconds(1800);

    /**
     * Converts to Spring CorsConfiguration
     * @return CorsConfiguration or null if no origins/origin patterns configured
     */
    public @Nullable CorsConfiguration toCorsConfiguration();
}

Web Endpoint Exposure

JMX Endpoint Exposure

Configures JMX MBean exposure of actuator endpoints.

@AutoConfiguration
@ConditionalOnBooleanProperty("spring.jmx.enabled")
public final class JmxEndpointAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean(JmxEndpointsSupplier.class)
    JmxEndpointDiscoverer jmxAnnotationEndpointDiscoverer(
        ParameterValueMapper parameterValueMapper,
        ObjectProvider<OperationInvokerAdvisor> invokerAdvisors,
        ObjectProvider<EndpointFilter<ExposableJmxEndpoint>> endpointFilters,
        ObjectProvider<OperationFilter<JmxOperation>> operationFilters
    );

    @Bean
    @ConditionalOnMissingBean(value = EndpointObjectNameFactory.class, search = SearchStrategy.CURRENT)
    DefaultEndpointObjectNameFactory endpointObjectNameFactory(MBeanServer mBeanServer);

    /**
     * JmxEndpointExporter is configured in nested configuration classes
     * See: JmxEndpointConfiguration and JmxEndpointDiscoveryConfiguration
     */
    @Bean
    JmxEndpointExporter jmxEndpointExporter(
        JmxEndpointDiscoverer jmxEndpointDiscoverer,
        EndpointObjectNameFactory endpointObjectNameFactory
    );
}

@ConfigurationProperties("management.endpoints.jmx")
public class JmxEndpointProperties {
    private String domain;
    private Properties staticNames = new Properties();
    private Exposure exposure = new Exposure();

    public static class Exposure {
        private Set<String> include = new LinkedHashSet<>();
        private Set<String> exclude = new LinkedHashSet<>();
    }
}

JMX Endpoint Exposure

Management Server Configuration

Configures a separate management server on a different port with independent SSL configuration.

/**
 * Auto-configuration for management context initialization
 * Creates child management context when using separate management port
 * Contains nested configurations for SAME and DIFFERENT management port types
 */
@AutoConfiguration
@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
public final class ManagementContextAutoConfiguration {

    /**
     * Configuration for when management endpoints run on same port as application
     * Validates that management-specific SSL and address are not configured
     * Adds 'local.management.port' property alias
     */
    @Configuration(proxyBeanMethods = false)
    @ConditionalOnManagementPort(ManagementPortType.SAME)
    static class SameManagementContextConfiguration implements SmartInitializingSingleton {

        /**
         * Constructor injecting environment for validation
         * @param environment Spring environment
         */
        SameManagementContextConfiguration(Environment environment);

        /**
         * Called after all singletons are instantiated
         * Performs validation and property alias setup
         */
        @Override
        void afterSingletonsInstantiated();

        /**
         * Inner configuration that enables ManagementContextConfiguration imports
         * for SAME context type
         */
        @Configuration(proxyBeanMethods = false)
        @EnableManagementContext(ManagementContextType.SAME)
        static class EnableSameManagementContextConfiguration {
        }
    }

    /**
     * Configuration for when management endpoints run on different port
     * Enables ManagementServerProperties and creates child context initializer
     */
    @Configuration(proxyBeanMethods = false)
    @ConditionalOnManagementPort(ManagementPortType.DIFFERENT)
    @EnableConfigurationProperties(ManagementServerProperties.class)
    static class DifferentManagementContextConfiguration {

        /**
         * Creates child management context initializer for separate management port
         * ManagementContextFactory is injected as parameter (not created by this config)
         * @param managementContextFactory Factory for creating management context
         * @param parentContext The parent application context
         * @return Child context initializer
         */
        @Bean
        static ChildManagementContextInitializer childManagementContextInitializer(
            ManagementContextFactory managementContextFactory,
            AbstractApplicationContext parentContext
        );
    }
}

@ConfigurationProperties("management.server")
public class ManagementServerProperties {
    private Integer port;
    private InetAddress address;
    private String basePath = "";

    /**
     * SSL configuration for management server
     * Type: org.springframework.boot.web.server.Ssl (from Spring Boot core)
     * Only applies when using separate management port (ManagementPortType.DIFFERENT)
     * Uses standard Spring Boot SSL configuration properties
     */
    private Ssl ssl;
}

public enum ManagementPortType {
    DISABLED,  // management.server.port=-1
    SAME,      // port not specified or same as server.port
    DIFFERENT; // different port specified

    public static ManagementPortType get(Environment environment);
}

Management Server Configuration

Conditional Annotations

Custom Spring conditional annotations for endpoint availability and configuration.

import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure;

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Conditional(OnAvailableEndpointCondition.class)
public @interface ConditionalOnAvailableEndpoint {
    Class<?> endpoint() default Void.class;
    Class<?> value() default Void.class;
    EndpointExposure[] exposure() default {};
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Conditional(OnEnabledInfoContributorCondition.class)
public @interface ConditionalOnEnabledInfoContributor {
    String value();
    InfoContributorFallback fallback() default InfoContributorFallback.USE_DEFAULTS_PROPERTY;
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Conditional(OnManagementPortCondition.class)
public @interface ConditionalOnManagementPort {
    ManagementPortType value();
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Configuration(proxyBeanMethods = false)
public @interface ManagementContextConfiguration {
    ManagementContextType value() default ManagementContextType.ANY;
    boolean proxyBeanMethods() default true;
}

Conditional Annotations

Endpoint Filtering and Discovery

Filters and discovers endpoints based on include/exclude patterns and access control.

public class IncludeExcludeEndpointFilter<E extends ExposableEndpoint<?>> implements EndpointFilter<E> {
    public IncludeExcludeEndpointFilter(Class<E> endpointType, Environment environment, String prefix, String... defaultIncludes);
    public IncludeExcludeEndpointFilter(Class<E> endpointType, Collection<String> include, Collection<String> exclude, String... defaultIncludes);

    public boolean match(E endpoint);
    public boolean match(EndpointId id);
}

public enum EndpointExposure {
    JMX,
    WEB;

    public String[] getDefaultIncludes();
}

public interface EndpointExposureOutcomeContributor {
    @Nullable
    ConditionOutcome getExposureOutcome(
        EndpointId endpointId,
        Set<EndpointExposure> exposures,
        ConditionMessage.Builder message
    );
}

Endpoint Filtering

Management Endpoints

Individual endpoint auto-configurations for monitoring, diagnostics, and application information.

Available Endpoints:

  • Audit Events (/auditevents) - Security audit event recording
  • Beans (/beans) - Application context bean information
  • Conditions (/conditions) - Auto-configuration report
  • Configuration Properties (/configprops) - @ConfigurationProperties beans
  • Environment (/env) - Environment properties and property sources
  • Heap Dump (/heapdump) - Heap dump download
  • HTTP Exchanges (/httpexchanges) - HTTP request/response recording
  • Info (/info) - Application information from contributors
  • Log File (/logfile) - Log file download
  • Loggers (/loggers) - Logger levels (view and modify)
  • Mappings (/mappings) - Request mapping paths
  • SBOM (/sbom) - Software Bill of Materials
  • Scheduled Tasks (/scheduledtasks) - Scheduled task information
  • Shutdown (/shutdown) - Graceful application shutdown
  • Startup (/startup) - Application startup information
  • Thread Dump (/threaddump) - Thread dump information
// Example: Beans Endpoint
@AutoConfiguration
@ConditionalOnAvailableEndpoint(endpoint = BeansEndpoint.class)
public final class BeansEndpointAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean
    BeansEndpoint beansEndpoint(ConfigurableApplicationContext applicationContext);
}

// Example: Conditions Report Endpoint
@Endpoint(id = "conditions")
public class ConditionsReportEndpoint {
    @ReadOperation
    public ConditionsDescriptor conditions();

    public static final class ConditionsDescriptor implements OperationResponseBody {
        private final Map<String, ContextConditionsDescriptor> contexts;

        /**
         * Creates a conditions descriptor
         * Private constructor - used internally by the endpoint
         * @param contexts Map of context ID to context conditions
         */
        private ConditionsDescriptor(Map<@Nullable String, ContextConditionsDescriptor> contexts);

        public Map<String, ContextConditionsDescriptor> getContexts();
    }

    @JsonInclude(Include.NON_EMPTY)
    public static final class ContextConditionsDescriptor {
        private final Map<String, List<MessageAndConditionDescriptor>> positiveMatches;
        private final Map<String, MessageAndConditionsDescriptor> negativeMatches;
        private final List<String> exclusions;
        private final Set<String> unconditionalClasses;
        private final @Nullable String parentId;

        /**
         * Creates a context conditions descriptor from application context
         * @param context The application context to analyze
         */
        public ContextConditionsDescriptor(ConfigurableApplicationContext context);

        public Map<String, List<MessageAndConditionDescriptor>> getPositiveMatches();
        public Map<String, MessageAndConditionsDescriptor> getNegativeMatches();
        public List<String> getExclusions();
        public Set<String> getUnconditionalClasses();
        public @Nullable String getParentId();
    }

    @JsonPropertyOrder({ "notMatched", "matched" })
    public static class MessageAndConditionsDescriptor {
        private final List<MessageAndConditionDescriptor> notMatched;
        private final List<MessageAndConditionDescriptor> matched;

        /**
         * Creates a descriptor from condition and outcomes
         * @param conditionAndOutcomes The conditions and their evaluation outcomes
         */
        public MessageAndConditionsDescriptor(ConditionAndOutcomes conditionAndOutcomes);

        public List<MessageAndConditionDescriptor> getNotMatched();
        public List<MessageAndConditionDescriptor> getMatched();
    }

    @JsonPropertyOrder({ "condition", "message" })
    public static class MessageAndConditionDescriptor {
        private final String condition;
        private final String message;

        /**
         * Creates a descriptor from single condition and outcome
         * @param conditionAndOutcome The condition and its evaluation outcome
         */
        public MessageAndConditionDescriptor(ConditionAndOutcome conditionAndOutcome);

        public String getCondition();
        public String getMessage();
    }
}

// Example: Info Endpoint with Contributors
@AutoConfiguration(after = InfoContributorAutoConfiguration.class)
@ConditionalOnAvailableEndpoint(endpoint = InfoEndpoint.class)
public final class InfoEndpointAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean
    InfoEndpoint infoEndpoint(ObjectProvider<InfoContributor> infoContributors);
}

@AutoConfiguration(after = ProjectInfoAutoConfiguration.class)
@EnableConfigurationProperties(InfoContributorProperties.class)
public final class InfoContributorAutoConfiguration {
    /**
     * The default order for the core {@link InfoContributor} beans.
     * Set to HIGHEST_PRECEDENCE + 10 to run before most other contributors.
     */
    public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 10;

    @Bean
    @Order(DEFAULT_ORDER)
    @ConditionalOnEnabledInfoContributor(value = "env", fallback = InfoContributorFallback.DISABLE)
    public EnvironmentInfoContributor envInfoContributor(ConfigurableEnvironment environment);

    @Bean
    @ConditionalOnEnabledInfoContributor("git")
    @ConditionalOnSingleCandidate(GitProperties.class)
    @ConditionalOnMissingBean
    @Order(DEFAULT_ORDER)
    public GitInfoContributor gitInfoContributor(GitProperties gitProperties, InfoContributorProperties infoContributorProperties);

    @Bean
    @ConditionalOnEnabledInfoContributor("build")
    @ConditionalOnSingleCandidate(BuildProperties.class)
    @Order(DEFAULT_ORDER)
    public InfoContributor buildInfoContributor(BuildProperties properties);

    @Bean
    @Order(DEFAULT_ORDER)
    @ConditionalOnEnabledInfoContributor(value = "java", fallback = InfoContributorFallback.DISABLE)
    public JavaInfoContributor javaInfoContributor();

    @Bean
    @Order(DEFAULT_ORDER)
    @ConditionalOnEnabledInfoContributor(value = "os", fallback = InfoContributorFallback.DISABLE)
    public OsInfoContributor osInfoContributor();

    @Bean
    @Order(DEFAULT_ORDER)
    @ConditionalOnEnabledInfoContributor(value = "process", fallback = InfoContributorFallback.DISABLE)
    public ProcessInfoContributor processInfoContributor();

    @Bean
    @Order(DEFAULT_ORDER)
    @ConditionalOnEnabledInfoContributor(value = "ssl", fallback = InfoContributorFallback.DISABLE)
    public SslInfoContributor sslInfoContributor(SslInfo sslInfo);

    @Bean
    @ConditionalOnMissingBean
    public SslInfo sslInfo(SslBundles sslBundles);
}

Management Endpoints

Endpoint Configuration Properties

Typed configuration classes for endpoint-specific settings.

import org.springframework.boot.actuate.endpoint.Show;

@ConfigurationProperties("management.endpoint.configprops")
public class ConfigurationPropertiesReportEndpointProperties {
    private Show showValues = Show.NEVER;
    private Set<String> roles = new LinkedHashSet<>();
}

@ConfigurationProperties("management.endpoint.env")
public class EnvironmentEndpointProperties {
    private Show showValues = Show.NEVER;
    private Set<String> roles = new LinkedHashSet<>();
}

// Note: Show enum is defined in org.springframework.boot.actuate.endpoint.Show
// (spring-boot-actuator module). See Type System Reference section below.

@ConfigurationProperties("management.endpoint.logfile")
public class LogFileWebEndpointProperties {
    private File externalFile;
}

@ConfigurationProperties("management.info")
public class InfoContributorProperties {
    private Git git = new Git();

    /**
     * Gets the Git info contributor properties
     * @return Git properties
     */
    public Git getGit();

    /**
     * Git info contributor properties
     */
    public static class Git {
        /**
         * Mode to use to expose git information
         * Default: SIMPLE
         *
         * Note: GitInfoContributor.Mode is from org.springframework.boot.actuate.info
         * (spring-boot-actuator module, not autoconfigure)
         */
        private GitInfoContributor.Mode mode = GitInfoContributor.Mode.SIMPLE;

        /**
         * Gets the git info mode
         * @return The git info mode
         */
        public GitInfoContributor.Mode getMode();

        /**
         * Sets the git info mode
         * @param mode The git info mode
         */
        public void setMode(GitInfoContributor.Mode mode);
    }
}

@ConfigurationProperties("management.httpexchanges")
public class HttpExchangesProperties {
    private Recording recording = new Recording();

    public static class Recording {
        /**
         * Items to be included in the exchange recording
         * Defaults to TIME_TAKEN, REQUEST_HEADERS, and RESPONSE_HEADERS
         * (excluding Authorization and Cookie headers)
         *
         * Note: Include enum is from org.springframework.boot.actuate.web.exchanges.Include
         * (spring-boot-actuator module, not autoconfigure)
         */
        private Set<Include> include = new HashSet<>(Include.defaultIncludes());

        /**
         * Include enum type - from spring-boot-actuator module
         * Package: org.springframework.boot.actuate.web.exchanges
         */
        public enum Include {
            REQUEST_HEADERS,
            RESPONSE_HEADERS,
            COOKIE_HEADERS,
            AUTHORIZATION_HEADER,
            TIME_TAKEN,
            PRINCIPAL,
            REMOTE_ADDRESS,
            SESSION_ID;

            /**
             * Returns the default includes: TIME_TAKEN, REQUEST_HEADERS, RESPONSE_HEADERS
             */
            public static Set<Include> defaultIncludes();
        }
    }
}

Endpoint Configuration Properties

Common Configuration Scenarios

Scenario 1: Development Environment

management.endpoints.web.exposure.include=*
management.endpoint.env.show-values=ALWAYS
management.endpoint.configprops.show-values=ALWAYS
management.httpexchanges.recording.include=REQUEST_HEADERS,RESPONSE_HEADERS,TIME_TAKEN

Scenario 2: Production Environment

management.endpoints.web.exposure.include=health,info,metrics,prometheus
management.endpoints.web.exposure.exclude=shutdown,heapdump,threaddump
management.endpoint.env.show-values=NEVER
management.endpoint.configprops.show-values=NEVER
management.server.port=8081
management.server.address=127.0.0.1

Scenario 3: Kubernetes/Docker

# Health checks on main port
management.endpoint.health.probes.enabled=true
server.port=8080

# Full actuator on separate internal port
management.server.port=8081
management.server.address=0.0.0.0
management.endpoints.web.exposure.include=*

Scenario 4: Secured Management with SSL

server.port=8080
management.server.port=8443
management.server.ssl.enabled=true
management.server.ssl.key-store=classpath:mgmt-keystore.p12
management.server.ssl.key-store-password=changeit
management.endpoints.web.exposure.include=health,info,metrics

Troubleshooting

Problem: Endpoints Not Accessible (404)

Possible causes:

  1. Endpoint not exposed: Check management.endpoints.web.exposure.include
  2. Endpoint disabled: Check management.endpoint.<id>.access or .enabled
  3. Wrong path: Verify management.endpoints.web.base-path and path mappings
  4. Wrong port: Check if using separate management port

Solution:

# Debug exposure
management.endpoints.web.exposure.include=*
logging.level.org.springframework.boot.actuate=DEBUG

Problem: Sensitive Information Exposed

Possible causes:

  1. show-values set to ALWAYS in production
  2. Too many endpoints exposed
  3. No authentication/authorization

Solution:

management.endpoint.env.show-values=NEVER
management.endpoint.configprops.show-values=NEVER
management.endpoints.web.exposure.include=health,info,metrics

Problem: Management Port Conflict

Symptom: Address already in use on management port

Solution:

# Change management port or use same port
management.server.port=8082
# OR
management.server.port=${server.port}

Problem: Custom Endpoint Not Registered

Possible causes:

  1. Missing @Component or @Bean registration
  2. @ConditionalOnAvailableEndpoint condition not met
  3. Endpoint not exposed in properties

Solution:

// Ensure @Component or @Bean
@Component
@Endpoint(id = "custom")
public class CustomEndpoint { }
# Ensure exposed
management.endpoint.custom.access=UNRESTRICTED
management.endpoints.web.exposure.include=custom

Problem: Info Endpoint Empty

Possible causes:

  1. No info contributors enabled
  2. No info.* properties set
  3. Missing git.properties or build-info.properties

Solution:

# Enable contributors
management.info.git.enabled=true
management.info.env.enabled=true
management.info.java.enabled=true

# Add custom info
info.app.name=My Application
info.app.version=1.0.0

Constraints and Limitations

Version-Specific

FeatureMin VersionNotes
Jackson 3 support4.0.0Jackson 2 deprecated, removed in 4.2.0
access property (vs enabled)3.4.0enabled deprecated
@ManagementContextConfiguration2.0.0For child context configuration
EndpointExposureOutcomeContributor3.4.0SPI for custom exposure logic

Technical Constraints

  1. Thread Safety: All endpoint operations must be thread-safe
  2. Performance: @ReadOperation methods should be fast (<1s typical)
  3. Memory: Heap dump endpoint generates files equal to heap size
  4. Network: Separate management port requires additional network configuration
  5. Security: Endpoints inherit security configuration from context

Endpoint-Specific Limitations

EndpointLimitationWorkaround
heapdumpOnly works with HotSpot JVMNot available on other JVMs
threaddumpMay impact performance under loadUse sampling profiler instead
logfileRequires file-based loggingConfigure logging.file.name
shutdownIrreversible operationRequires explicit enablement
httpexchangesIn-memory only, limited capacityUse dedicated APM tool for production
auditeventsRequires AuditEventRepository beanImplement custom repository
startupRequires BufferingApplicationStartupConfigure at application start

Anti-Patterns

❌ Anti-Pattern 1: Exposing All Endpoints in Production

# DON'T
management.endpoints.web.exposure.include=*

Why: Exposes sensitive information and dangerous operations.

Do instead:

# DO
management.endpoints.web.exposure.include=health,info,metrics,prometheus

❌ Anti-Pattern 2: Always Showing Sensitive Values

# DON'T
management.endpoint.env.show-values=ALWAYS
management.endpoint.configprops.show-values=ALWAYS

Why: Exposes secrets, passwords, API keys.

Do instead:

# DO
management.endpoint.env.show-values=WHEN_AUTHORIZED
management.endpoint.env.roles=ADMIN

❌ Anti-Pattern 3: No Authentication on Management Endpoints

// DON'T
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) {
    http.authorizeHttpRequests(auth -> auth.anyRequest().permitAll());
    return http.build();
}

Do instead:

// DO
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) {
    http.securityMatcher(EndpointRequest.toAnyEndpoint())
        .authorizeHttpRequests(auth -> auth
            .requestMatchers(EndpointRequest.to("health", "info")).permitAll()
            .anyRequest().hasRole("ACTUATOR"));
    return http.build();
}

❌ Anti-Pattern 4: Blocking Operations in Endpoints

// DON'T
@Endpoint(id = "slow")
public class SlowEndpoint {
    @ReadOperation
    public String getData() throws InterruptedException {
        Thread.sleep(30000); // Blocks for 30 seconds
        return "data";
    }
}

Do instead:

// DO
@Endpoint(id = "fast")
public class FastEndpoint {
    @ReadOperation
    public String getData() {
        return cache.get("data"); // Quick cache lookup
    }
}

Type System Reference

Core Enums

/**
 * Endpoint access levels
 * Controls what operations can be performed on an endpoint
 * @since 3.4.0
 */
public enum Access {
    /**
     * UNRESTRICTED - Full access to all operations
     * Allows READ, WRITE, and DELETE operations
     * Use for: Public endpoints like health, info
     */
    UNRESTRICTED,

    /**
     * READ_ONLY - Read operations only
     * Allows READ operations, blocks WRITE and DELETE
     * Use for: Endpoints that should be monitored but not modified (beans, env, metrics)
     */
    READ_ONLY,

    /**
     * NONE - Endpoint is disabled
     * Blocks all operations, endpoint will not be exposed
     * Use for: Disabling specific endpoints (shutdown, threaddump in production)
     */
    NONE
}

/**
 * Operation types for endpoints
 */
public enum OperationType {
    READ,    // Query operation (safe, idempotent) - maps to HTTP GET
    WRITE,   // Mutating operation - maps to HTTP POST/PUT
    DELETE   // Deletion operation - maps to HTTP DELETE
}

/**
 * Endpoint exposure technologies
 */
public enum EndpointExposure {
    JMX,  // JMX MBean exposure
    WEB;  // HTTP/JSON exposure

    /**
     * Gets default includes for this exposure type
     * @return Array of endpoint IDs to include by default
     */
    public String[] getDefaultIncludes();
}

/**
 * Management port types for @ConditionalOnManagementPort
 */
public enum ManagementPortType {
    /**
     * Management endpoints disabled (management.server.port=-1)
     */
    DISABLED,

    /**
     * Management endpoints on same port as application
     * Used when management.server.port is not set or same as server.port
     */
    SAME,

    /**
     * Management endpoints on separate port
     * Used when management.server.port is set to a different port
     */
    DIFFERENT;

    /**
     * Determines the management port type from environment
     * @param environment Spring environment
     * @return The management port type
     */
    public static ManagementPortType get(Environment environment);
}

/**
 * Management context types for @ManagementContextConfiguration
 * @since 2.0.0
 */
public enum ManagementContextType {
    /**
     * Management endpoints in same context as application
     * Used when management.server.port is not set or same as server.port
     */
    SAME,

    /**
     * Management endpoints in separate child context
     * Used when management.server.port is set to a different port
     */
    CHILD,

    /**
     * Configuration applies to any context type (default)
     * Used for configurations that should be available in both SAME and CHILD contexts
     */
    ANY
}

/**
 * Controls when to show unsanitized property values in endpoints
 * Used by ConfigurationPropertiesReportEndpointProperties and EnvironmentEndpointProperties
 * Located in: org.springframework.boot.actuate.endpoint.Show (spring-boot-actuator module)
 * @since 2.0.0
 */
public enum Show {
    /**
     * Never show unsanitized values (always sanitize sensitive data)
     */
    NEVER,

    /**
     * Always show unsanitized values (not recommended in production)
     */
    ALWAYS,

    /**
     * Show unsanitized values only when user has required roles
     */
    WHEN_AUTHORIZED
}

/**
 * Info contributor fallback behavior
 */
public enum InfoContributorFallback {
    USE_DEFAULTS_PROPERTY,  // Use management.info.defaults.enabled as fallback
    DISABLE                 // Disable if specific property not set
}

Core Interfaces

/**
 * Filters endpoints based on custom criteria
 * @param <E> Type of exposable endpoint
 */
@FunctionalInterface
public interface EndpointFilter<E extends ExposableEndpoint<?>> {
    /**
     * Tests if an endpoint should be included
     * @param endpoint The endpoint to test
     * @return true if endpoint should be included, false otherwise
     */
    boolean match(E endpoint);
}

/**
 * Resolves endpoint access levels from configuration
 */
public interface EndpointAccessResolver {
    /**
     * Determines the access level for an endpoint
     * @param endpointId The endpoint identifier
     * @param defaultAccess The default access level
     * @return The resolved access level
     */
    Access accessFor(EndpointId endpointId, Access defaultAccess);
}

/**
 * Contributes information to the info endpoint
 */
public interface InfoContributor {
    /**
     * Contributes information to the info endpoint
     * @param builder The info builder
     */
    void contribute(Info.Builder builder);
}

/**
 * Maps parameter values from strings to required types
 * Used when invoking endpoint operations via web or JMX
 */
public interface ParameterValueMapper {
    /**
     * Maps a parameter value to the required type
     * @param parameter Operation parameter metadata
     * @param value String value from request (may be null)
     * @return Converted value
     * @throws ParameterMappingException if conversion fails
     */
    Object mapParameterValue(OperationParameter parameter, @Nullable Object value)
        throws ParameterMappingException;
}

/**
 * Maps endpoint IDs to URL paths
 */
public interface PathMapper {
    /**
     * Gets the root path for an endpoint
     * @param endpointId Endpoint ID
     * @return Root path (e.g., "health" or "healthcheck")
     */
    String getRootPath(EndpointId endpointId);
}

/**
 * Invokes an endpoint operation
 */
@FunctionalInterface
public interface OperationInvoker {
    /**
     * Invokes the operation
     * @param context The invocation context
     * @return The operation result
     */
    Object invoke(InvocationContext context);
}

/**
 * Applies caching behavior to endpoint operations
 */
public interface CachingOperationInvokerAdvisor {
    /**
     * Applies caching to an operation invoker
     * @param endpointId Endpoint ID
     * @param operationType Operation type (READ, WRITE, DELETE)
     * @param parameters Operation parameters
     * @param invoker Original invoker
     * @return Wrapped invoker with caching
     */
    OperationInvoker apply(
        EndpointId endpointId,
        OperationType operationType,
        OperationParameters parameters,
        OperationInvoker invoker
    );
}

/**
 * Provides endpoint identifier
 */
public interface EndpointIdProvider {
    /**
     * Gets the endpoint ID
     * @return The endpoint ID
     */
    EndpointId getEndpointId();
}

/**
 * Supplies a collection of endpoints
 * @param <E> Type of exposable endpoint
 */
@FunctionalInterface
public interface EndpointsSupplier<E extends ExposableEndpoint<?>> {
    /**
     * Gets all endpoints
     * @return Collection of endpoints
     */
    Collection<E> getEndpoints();
}

/**
 * Creates JMX object names for endpoints
 */
public interface EndpointObjectNameFactory {
    /**
     * Gets the JMX ObjectName for an endpoint
     * @param endpoint The JMX endpoint
     * @return The ObjectName
     * @throws MalformedObjectNameException if the name is invalid
     */
    ObjectName getObjectName(ExposableJmxEndpoint endpoint) throws MalformedObjectNameException;
}

/**
 * Contributes to endpoint exposure outcome determination
 * @since 3.4.0
 */
public interface EndpointExposureOutcomeContributor {
    /**
     * Gets the exposure outcome for an endpoint
     * @param endpointId The endpoint ID
     * @param exposures The exposure technologies
     * @param message Message builder for logging
     * @return The condition outcome, or null to continue evaluation
     */
    @Nullable
    ConditionOutcome getExposureOutcome(
        EndpointId endpointId,
        Set<EndpointExposure> exposures,
        ConditionMessage.Builder message
    );
}

Core Classes

/**
 * Represents an endpoint identifier
 * Immutable, normalized representation of an endpoint ID
 */
public final class EndpointId {
    /**
     * Creates an endpoint ID from a string value
     * @param value The endpoint ID value (e.g., "health", "custom-endpoint")
     * @return The endpoint ID
     * @throws IllegalArgumentException if value is invalid
     */
    public static EndpointId of(String value);

    /**
     * Creates an endpoint ID from a property value
     * Normalizes the value (e.g., converts kebab-case/snake_case to lowercase)
     * @param value The property value
     * @return The endpoint ID
     */
    public static EndpointId fromPropertyValue(String value);

    /**
     * Returns the string representation of this endpoint ID
     * @return The endpoint ID as a string
     */
    @Override
    public String toString();

    /**
     * Returns the lower-case string representation of this endpoint ID
     * @return The endpoint ID as a lower-case string
     */
    public String toLowerCaseString();

    /**
     * Compares this endpoint ID to another object
     * @param obj The object to compare
     * @return true if equal
     */
    @Override
    public boolean equals(Object obj);

    /**
     * Returns the hash code for this endpoint ID
     * @return The hash code
     */
    @Override
    public int hashCode();
}

/**
 * Context for operation invocation
 */
public interface InvocationContext {
    /**
     * Gets the operation arguments
     * @return Map of argument names to values
     */
    Map<String, Object> getArguments();

    /**
     * Gets the security context
     * @return The security context
     */
    SecurityContext getSecurityContext();
}

/**
 * Exception thrown when parameter mapping fails
 */
public class ParameterMappingException extends RuntimeException {
    public ParameterMappingException(String message, Throwable cause);
}

/**
 * Media types supported by endpoints
 */
public class EndpointMediaTypes {
    private final List<String> produced;
    private final List<String> consumed;

    /**
     * Creates endpoint media types
     * @param produced Media types produced by endpoints
     * @param consumed Media types consumed by endpoints
     */
    public EndpointMediaTypes(List<String> produced, List<String> consumed);

    /**
     * Gets media types produced by endpoints
     * @return Produced media types
     */
    public List<String> getProduced();

    /**
     * Gets media types consumed by endpoints
     * @return Consumed media types
     */
    public List<String> getConsumed();
}

/**
 * Collection of all path-mapped endpoints
 */
public class PathMappedEndpoints implements Iterable<PathMappedEndpoint> {

    /**
     * Gets the base path for all endpoints
     * @return Base path (e.g., "/actuator")
     */
    public String getBasePath();

    /**
     * Gets root path for endpoint with given ID
     * @param endpointId Endpoint ID
     * @return Root path or null if not found
     */
    public String getRootPath(EndpointId endpointId);

    /**
     * Gets full path for endpoint with given ID
     * @param endpointId Endpoint ID
     * @return Full path (base path + root path) or null if not found
     */
    public String getPath(EndpointId endpointId);

    /**
     * Gets endpoint by ID
     * @param endpointId Endpoint ID
     * @return PathMappedEndpoint or null if not found
     */
    public PathMappedEndpoint getEndpoint(EndpointId endpointId);

    /**
     * Gets all root paths (excluding additional paths)
     * @return Collection of root paths
     */
    public Collection<String> getAllRootPaths();

    /**
     * Gets all full paths (excluding additional paths)
     * @return Collection of full paths
     */
    public Collection<String> getAllPaths();

    /**
     * Gets additional paths for given endpoint
     * @param webServerNamespace Web server namespace
     * @param endpointId Endpoint ID
     * @return Collection of additional paths
     * @since 3.4.0
     */
    public Collection<String> getAdditionalPaths(WebServerNamespace webServerNamespace, EndpointId endpointId);

    /**
     * Streams all path-mapped endpoints
     * @return Stream of endpoints
     */
    public Stream<PathMappedEndpoint> stream();

    /**
     * Returns an iterator over path-mapped endpoints
     * @return Iterator of endpoints
     */
    @Override
    public Iterator<PathMappedEndpoint> iterator();
}

/**
 * Web operation request predicate
 */
public class WebOperationRequestPredicate {
    private final String path;
    private final WebEndpointHttpMethod httpMethod;
    private final Collection<String> consumes;
    private final Collection<String> produces;

    /**
     * Gets the operation path
     * @return The path
     */
    public String getPath();

    /**
     * Gets the HTTP method
     * @return The HTTP method
     */
    public WebEndpointHttpMethod getHttpMethod();

    /**
     * Gets the consumed media types
     * @return Consumed media types
     */
    public Collection<String> getConsumes();

    /**
     * Gets the produced media types
     * @return Produced media types
     */
    public Collection<String> getProduces();
}

/**
 * HTTP methods for web operations
 */
public enum WebEndpointHttpMethod {
    GET,
    POST,
    DELETE
}

Integration with Spring Boot Features

Spring Security

@Configuration
public class ActuatorSecurityConfiguration {

    @Bean
    public SecurityFilterChain actuatorSecurity(HttpSecurity http) throws Exception {
        http.securityMatcher(EndpointRequest.toAnyEndpoint())
            .authorizeHttpRequests(auth -> auth
                .requestMatchers(EndpointRequest.to("health", "info")).permitAll()
                .requestMatchers(EndpointRequest.to("metrics", "prometheus")).hasRole("METRICS")
                .anyRequest().hasRole("ACTUATOR"))
            .httpBasic(Customizer.withDefaults());
        return http.build();
    }
}

Spring Boot Admin

# Client configuration
spring.boot.admin.client.url=http://admin-server:8080
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always

Prometheus

management.endpoints.web.exposure.include=health,prometheus
management.metrics.export.prometheus.enabled=true

Micrometer

@Configuration
public class MetricsConfiguration {

    @Bean
    public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
        return registry -> registry.config()
            .commonTags("application", "my-app", "region", "us-east");
    }
}

Migration Guide

From Spring Boot 3.x to 4.0

Breaking changes:

  1. Jackson 2 → Jackson 3: Update to Jackson 3 (Jackson 2 support deprecated)

    <!-- Update dependency -->
    <dependency>
      <groupId>tools.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
    </dependency>
  2. enabled → access: Migrate from .enabled to .access properties

    # OLD (deprecated)
    management.endpoint.health.enabled=true
    
    # NEW
    management.endpoint.health.access=UNRESTRICTED
  3. @ControllerEndpoint/@ServletEndpoint: Migrate to @Endpoint with extensions

    // OLD (deprecated since 3.3.0, scheduled for removal)
    @ControllerEndpoint(id = "custom")
    
    // NEW
    @Endpoint(id = "custom")
    @WebEndpoint

Extension Points

Custom Endpoint Filter

@Bean
public EndpointFilter<ExposableWebEndpoint> customFilter() {
    return endpoint -> {
        // Custom filtering logic
        return !endpoint.getEndpointId().toString().startsWith("internal");
    };
}

Custom Access Resolver

@Bean
public EndpointAccessResolver customAccessResolver() {
    return (endpointId, defaultAccess) -> {
        if (endpointId.toString().equals("shutdown")) {
            return Access.NONE;
        }
        return defaultAccess;
    };
}

Custom Path Mapper

@Bean
public PathMapper customPathMapper() {
    return endpointId -> {
        String id = endpointId.toString();
        return switch (id) {
            case "health" -> "status";
            case "info" -> "about";
            default -> id;
        };
    };
}

Custom Exposure Outcome Contributor

// Register in META-INF/spring/...EndpointExposureOutcomeContributor.imports
public class CustomExposureContributor implements EndpointExposureOutcomeContributor {
    @Override
    public ConditionOutcome getExposureOutcome(EndpointId id, Set<EndpointExposure> exposures, ConditionMessage.Builder message) {
        // Custom exposure logic
        return null; // or ConditionOutcome
    }
}

Performance Considerations

Caching Strategy

# Enable caching for expensive endpoints
management.endpoint.beans.cache.time-to-live=10s
management.endpoint.conditions.cache.time-to-live=30s
management.endpoint.mappings.cache.time-to-live=60s

HTTP Exchanges Memory Impact

# Limit recording to reduce memory
management.httpexchanges.recording.include=TIME_TAKEN
# Default capacity: 100 entries
# Memory: ~1KB per exchange

Thread Pool Considerations

When using separate management port:

  • Separate Tomcat connector with independent thread pool
  • Default: 200 threads (configurable via server properties)
  • Management requests don't compete with application requests

Testing

Testing Custom Endpoints

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class CustomEndpointTest {

    @LocalManagementPort
    private int managementPort;

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    void customEndpointReturnsData() {
        String url = "http://localhost:" + managementPort + "/actuator/custom";
        ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
    }
}

Testing Endpoint Availability

@SpringBootTest(properties = {
    "management.endpoint.custom.access=UNRESTRICTED",
    "management.endpoints.web.exposure.include=custom"
})
class EndpointAvailabilityTest {

    @Autowired
    private ApplicationContext context;

    @Test
    void customEndpointIsRegistered() {
        assertThat(context.containsBean("customEndpoint")).isTrue();
    }
}

Architecture Integration Flow

Understanding how the subsystems work together:

Application Startup
    ↓
1. Core Infrastructure Setup
   → [core-infrastructure.md](./core-infrastructure.md)
   - EndpointAutoConfiguration creates parameter mappers, caching, access resolvers
   - PropertiesEndpointAccessResolver reads access properties
    ↓
2. Endpoint Discovery & Registration
   → [management-endpoints.md](./management-endpoints.md)
   - Individual endpoint auto-configurations register endpoint beans
   - @ConditionalOnAvailableEndpoint checks exposure/access via [conditional-annotations.md](./conditional-annotations.md)
    ↓
3. Endpoint Filtering
   → [endpoint-filtering.md](./endpoint-filtering.md)
   - IncludeExcludeEndpointFilter applies include/exclude patterns
   - EndpointExposureOutcomeContributor (SPI) provides custom logic
    ↓
4. Exposure Configuration
   → [web-endpoints.md](./web-endpoints.md) | [jmx-endpoints.md](./jmx-endpoints.md)
   - WebEndpointAutoConfiguration exposes via HTTP
   - JmxEndpointAutoConfiguration exposes via JMX MBeans
   - PathMapper maps endpoint IDs to URL paths
    ↓
5. Management Server Setup (Optional)
   → [management-server.md](./management-server.md)
   - ManagementContextAutoConfiguration creates separate server if configured
   - Separate port with independent SSL, thread pool, and context
    ↓
6. Endpoint Configuration
   → [endpoint-properties.md](./endpoint-properties.md)
   - Endpoint-specific properties applied (show-values, roles, recording, etc.)
    ↓
7. Runtime Operation
   - Incoming request → PathMappedEndpoints → WebOperation
   - OperationFilter applies access control
   - ParameterValueMapper converts parameters
   - CachingOperationInvokerAdvisor caches if configured
   - Operation invoked → Response returned

Cross-Document Navigation Map

Starting PointRelated DocumentsPurpose

If You Need To...Start HereThen CheckFinally See
Configure endpoint exposureweb-endpoints.mdendpoint-filtering.mdconditional-annotations.md
Secure endpointscore-infrastructure.md (Access Control)endpoint-filtering.md (Filtering)web-endpoints.md (CORS)
Create custom endpointmanagement-endpoints.md (Examples)core-infrastructure.md (Infrastructure)web-endpoints.md (Exposure)
Separate management portmanagement-server.mdweb-endpoints.md (Properties)endpoint-properties.md (SSL Config)
Control access per-endpointcore-infrastructure.md (Access Resolver)endpoint-properties.md (Per-endpoint props)endpoint-filtering.md (Operation filters)
Configure JMX exposurejmx-endpoints.mdendpoint-filtering.md (Include/exclude)conditional-annotations.md (@ConditionalOn...)
Debug why endpoint not availableendpoint-filtering.md (Filtering logic)conditional-annotations.md (Conditions)core-infrastructure.md (Access levels)
Configure CORS for endpointsweb-endpoints.md (CORS section)endpoint-properties.md (Properties)-

Component Interaction Matrix

Shows which documents cover interactions between components:

Component AComponent BInteraction Documented In
EndpointAutoConfigurationWebEndpointAutoConfigurationcore-infrastructure.md, web-endpoints.md
IncludeExcludeEndpointFilter@ConditionalOnAvailableEndpointendpoint-filtering.md, conditional-annotations.md
WebEndpointPropertiesPathMapperweb-endpoints.md
ManagementServerPropertiesManagementContextAutoConfigurationmanagement-server.md
PropertiesEndpointAccessResolverEndpointFiltercore-infrastructure.md, endpoint-filtering.md
Individual EndpointsInfoContributormanagement-endpoints.md
CorsEndpointPropertiesWebEndpointAutoConfigurationweb-endpoints.md, endpoint-properties.md

Quick Problem Resolution Path

ProblemCheck These Docs (In Order)
Endpoint returns 4041. endpoint-filtering.md (exposure)<br>2. web-endpoints.md (path mapping)<br>3. management-server.md (port)
Endpoint shows wrong values1. endpoint-properties.md (show-values)<br>2. management-endpoints.md (endpoint config)
Cannot write to endpoint1. core-infrastructure.md (access levels)<br>2. endpoint-filtering.md (operation filters)
CORS errors1. web-endpoints.md (CORS config)<br>2. endpoint-properties.md (properties)
Custom endpoint not registered1. conditional-annotations.md (conditions)<br>2. endpoint-filtering.md (filtering)<br>3. management-endpoints.md (registration)
Management port conflict1. management-server.md (port config)<br>2. web-endpoints.md (base path)

Related Documentation

Internal Tile Documentation

Detailed subsystem documentation (see Subsystems Reference above):

External Documentation

Related Spring Boot and monitoring ecosystem:

  • Spring Boot Actuator (Core) - Endpoint abstractions and interfaces
  • Spring Boot Actuator Metrics - Metrics collection and export via Micrometer
  • Spring Boot Admin - External monitoring tool and admin UI
  • Micrometer - Metrics facade for multiple monitoring systems (Prometheus, Datadog, etc.)
  • Spring Security - Securing actuator endpoints with authentication and authorization