Configuring Spring Boot Starter

How to wire the Axelix Spring Boot Starter into a Spring Boot application so Axelix Master can discover it, read its state, and act on it.

This page shows how to wire the Axelix Spring Boot Starter into a Spring Boot application so Axelix Master can discover it, read its state, and act on it — both from the UI and through Master's bundled MCP (Model Context Protocol) server, which exposes the same data to AI agents. Pick the starter module matching your Boot major version, expose the Axelix actuator endpoints (automatic as of Axelix 1.2.0), share the JWT signing key with Master, and tell Master where to find the instance.

Before you start

A few facts worth pinning down before you copy any of the snippets below.

  • Three starter modules, one per Spring Boot major version. Pick the one that matches the Boot version your application already uses:
    • com.axelixlabs:axelix-spring-boot-2-starter — Spring Boot 2.x (built and tested against 2.7.18, Spring Cloud 2021.0.9, minimum JDK 11).
    • com.axelixlabs:axelix-spring-boot-3-starter — Spring Boot 3.x (built and tested against 3.0.13, Spring Cloud 2022.0.4, minimum JDK 17).
    • com.axelixlabs:axelix-spring-boot-4-starter — Spring Boot 4.x (built and tested against 4.0.6, Spring Cloud 2025.1.0, minimum JDK 17).
  • What the starter contributes: a set of Axelix-specific actuator endpoints (axelix-metadata, axelix-beans, axelix-loggers, …), a JWT-based authorization filter that gates them, and an optional self-registration component that announces this instance to Master.
  • The Axelix build plugin is required too: alongside the starter dependency, apply the Axelix Gradle or Maven build plugin. It stamps your build coordinates (groupId/artifactId/version) into the artifact, and Master identifies every application by those coordinates — an instance built without the plugin cannot register. See What is the Axelix build plugin? and Configuring the build plugin.
  • Two consumers of the same data: Master serves the Axelix UI at / and an MCP server at /api/mcp (controlled by axelix.master.mcp-server.enabled, on by default). Both read from the actuator endpoints the starter exposes, so wiring the starter up makes the instance visible to UI users and to MCP clients with no extra configuration on the starter side.
  • What Master needs to talk to the instance: HTTP reachability to the application's actuator base path (default /actuator), the Axelix endpoints exposed through management.endpoints.web.exposure.include, and a JWT signing key identical to the one configured on Master — see Authentication — JWT for the master side.
  • Two ways Master finds the instance:
    • Master-side autodiscovery — Master scans its environment (currently Kubernetes Services) and probes the actuator endpoint itself. The starter only needs to expose the endpoints; nothing additional to configure.
    • Self-registration — the starter posts a heartbeat to Master on a fixed interval. Use this when Master cannot scan the instance's environment (different network, no platform integration, plain VMs).

Add the dependency

Declare the starter coordinate matching your Boot major version.

The snippets below pin 1.0.0 for illustration. Check the Maven Central for the latest published tag and use that version in your own build.

build.gradle.kts
dependencies {
    implementation("com.axelixlabs:axelix-spring-boot-4-starter:1.0.0")
}

The starter also depends on Spring Boot Actuator if your application doesn't already include spring-boot-starter-actuator, add it alongside.

The build plugin is a separate step

Applying the Axelix build plugin is required for every managed service, but it lives in its own section — see What is the Axelix build plugin? and Configuring the build plugin.

Actuator endpoints

Starting with Axelix 1.2.0 there is nothing to configure by hand: on application startup the starter adds its own actuator endpoints to management.endpoints.web.exposure.include, so Master can reach them out of the box. On older versions the starter does not do this, and the endpoints must be listed manually — see Exposing the endpoints on Axelix below 1.2.0.

What the starter exposes

The starter exposes the following endpoints:

EndpointPurpose
axelix-metadata requiredService metadata; the one Master probes first
axelix-detailsSummary information about the instance
axelix-beansContext beans
axelix-cachesCaches (when a CacheManager is present)
axelix-conditionsAuto-configuration conditions report
axelix-configprops@ConfigurationProperties
axelix-envEnvironment and property sources
axelix-feignFeign clients (when Feign is on the classpath)
axelix-gcGarbage collection
axelix-heap-dumpHeap dump
axelix-loggersLogging levels
axelix-metricsMetrics
axelix-scheduled-tasksScheduled tasks
axelix-thread-dumpThread dump
axelix-dependenciesDependency SBOM

Endpoints that don't apply to your application stay inert — the starter activates each one only when its prerequisites are met (for example, axelix-feign without Feign on the classpath or axelix-caches without a CacheManager never come up).

As of Axelix 1.2.0 the native health and info endpoints are no longer required, so the starter never exposes them on its own (before 1.2.0 Axelix depended on them, and the starter force-exposed both). Only the endpoints you list in management.endpoints.web.exposure.include plus the Axelix ones are exposed — add health and info to the list yourself when you need them, including the health endpoint that Spring Boot would otherwise expose by default.

Adding your own endpoints

If you need your own actuator endpoints, just list only them — the starter merges your list with its own instead of replacing it.

management:
  endpoints:
    web:
      exposure:
        include:
          - prometheus

The result is that prometheus and all the Axelix endpoints are exposed.

The * value is supported too — everything gets exposed and the starter leaves the list alone.

Exposing the endpoints on Axelix below 1.2.0

LegacyOnly needed before release: 1.2.0. On later versions, skip this section.

Starters older than 1.2.0 do not add their endpoints to the exposure list themselves, so every Axelix endpoint you want Master to read has to be listed in management.endpoints.web.exposure.include by hand. At minimum expose axelix-metadata — without it the instance never appears in Master — and in practice the whole set, so every UI section has data to show. The health and info endpoints are force-exposed by those starter versions on their own, so you do not need to list them:

management:
  endpoints:
    web:
      exposure:
        include:
          - axelix-metadata
          - axelix-beans
          - axelix-caches
          - axelix-conditions
          - axelix-configprops
          - axelix-details
          - axelix-env
          - axelix-feign
          - axelix-gc
          - axelix-heap-dump
          - axelix-loggers
          - axelix-metrics
          - axelix-scheduled-tasks
          - axelix-thread-dump

Export Axelix metrics through Micrometer

The axelix-metrics actuator endpoint powers the Axelix UI. In addition, the Spring Boot starters can publish a small set of Axelix-specific meters into your application's own Micrometer MeterRegistry.

This export path switches on automatically when a MeterRegistry bean is present. There is no extra Axelix property for it. The starter registers these meters:

MeterTypeTagsMeaning
axelix_transaction_durationTimerclass, methodDuration of each monitored @Transactional execution. The timer also publishes 0.5, 0.95, and 0.99 percentiles.
axelix_transaction_queriesCounterclass, methodTotal number of SQL queries executed inside monitored transactions.
axelix_transaction_external_callsCounterclass, methodTotal number of external calls (e.g. RestTemplate) made inside monitored transactions.
axelix_cache_requestsCountercache, resultTotal number of cache lookups recorded by Axelix-enhanced caches.
axelix_cache_enabledGaugecacheCurrent runtime state of each enhanced cache: 1 when enabled, 0 when disabled.

These meters complement the UI-facing actuator endpoints rather than replace them. The UI still reads axelix-metrics and axelix-caches. Transaction monitoring data is not served by a dedicated actuator endpoint — it travels to Master as part of the instance's registration metadata exposed through axelix-metadata (see Transaction monitoring).

Share the JWT signing key with Master

Every Axelix actuator endpoint is gated by JwtAuthorizationFilter. The filter expects an HS256, HS384, or HS512 token signed with the same key Master uses, so the two sides must agree on the algorithm and the secret. Use the same value you set for axelix.master.auth.jwt.signing-key on Master.

axelix:
  sbs:
    auth:
      jwt:
        algorithm: HMAC512
        signing-key: ${AXELIX_JWT_SIGNING_KEY}
        duration: 5m

algorithm and signing-key are mandatory — startup fails fast with a clear message if either is missing. duration controls how long the starter-issued token used for self-registration heartbeats is valid, the default is five minutes, after which the starter rotates it automatically.

A signing key shared between Master and every monitored service is a sensitive secret. Inject it through an environment variable, mounted file, or secret manager — not a checked-in YAML.

Let Master find the instance

Pick one of the two paths below. They are mutually exclusive in practice — self-registration only adds latency if Master can already scan the environment.

Option A — Master-side autodiscovery

When Master runs inside a Kubernetes cluster alongside your services, the simplest setup is to let Master scan the namespace for Services and probe each one's /actuator/axelix-metadata. No further configuration is needed on the starter side beyond exposing the actuator endpoints and sharing the JWT signing key. Configure the master-side scan with axelix.master.discovery.auto.* — see Discovery — auto-discovery on the Master page.

Option B — Self-registration

When Master cannot scan the instance's environment — a different cluster, a plain VM, an isolated network — switch on self-registration in the starter. The instance then posts a heartbeat carrying its actuator URL to Master on a fixed interval. Master accepts the post at POST /api/internal/service/register, which is also where you point axelix.sbs.discovery.master-url.

axelix:
  sbs:
    discovery:
      self-registration: true
      master-url: http://master.internal:8080/api/internal/service/register
      instance-actuator-url: http://my-app.internal:8080/actuator
      instance-name: orders-service
      heartbeat-interval: 15s

A few details that catch people out:

  • instance-actuator-url is the base URL of the service as Master will reach it from its own network — host and port only.
  • master-url is the full URL including /api/internal/service/register. The starter posts to it verbatim.
  • instance-name is the label Master shows for this instance in the UI and in MCP responses. Pick a name that survives restarts and replicas — typically the service name, not the pod name.
  • Self-registration is accepted by Master out of the box (axelix.master.discovery.self-registration.enabled is true by default), set it to false if you want to refuse heartbeats. Master evicts an instance after axelix.master.discovery.self-registration.eviction.heartbeat-timeout of silence (45s by default), so keep heartbeat-interval comfortably under that.

Sanitize sensitive property values

The Axelix axelix-env and axelix-configprops endpoints return property values to Master. To keep secrets out of casual reads, the starter masks values it returns to callers that lack the right authority. The mechanism is the same for both endpoints, controlled by a single starter property:

axelix.sbs.endpoints.config.sanitized-properties

  • Empty list (default) — every value returned by axelix-env and axelix-configprops is replaced with ****** for callers without the relevant authority. The default is intentionally conservative: no opt-in needed to be safe.
  • Non-empty list — only the listed keys are masked; everything else is returned raw to any caller. Use this when the conservative default is too aggressive and you want to mask only specific keys (passwords, tokens, signing keys).

Authority is checked per-endpoint:

  • axelix-env — the ENV_VALUES_READ authority lets the caller see raw values.
  • axelix-configprops — the CONFIG_PROPS_VALUES_READ authority lets the caller see raw values.

Both authorities are granted by Master's built-in ADMIN and SUPER_ADMIN roles. VIEWER and EDITOR always go through the sanitization function. See Roles and authorities for the full matrix.

axelix:
  sbs:
    endpoints:
      config:
        sanitized-properties:
          - database.password
          - spring.datasource.password
          - jwt.signing-key

The standard Spring Boot Actuator masking switches — management.endpoint.env.show-values, management.endpoint.env.keys-to-sanitize, and their configprops equivalents — are not consulted.

Configuration reference

Every starter property lives under the axelix.sbs.* namespace.

Disabling the starter

UpcomingAvailable in an upcoming minor release

axelix.sbs.enabled is the global switch for the whole starter. It is true by default, so adding the dependency is enough to activate everything described on this page. Set it to false and every Axelix auto-configuration backs off: no Axelix actuator endpoints, no JWT authorization filter, no self-registration heartbeats, no Micrometer meters, and no transaction monitoring. The application then starts as if the starter were not on the classpath, while the dependency itself stays in the build.

Reach for this switch when you want Axelix off in a specific environment — for example locally or in a test profile — without maintaining a separate dependency set. It is also a quick way to rule the starter out while troubleshooting startup issues.

axelix:
  sbs:
    enabled: false

The property is read once, during startup. As a result, changing it requires a restart of the application.

With the starter disabled, Master loses sight of the instance: autodiscovery probes to /actuator/axelix-metadata fail, and self-registration heartbeats stop, so the instance disappears from the UI and from MCP responses.

PropertyDefaultDescription
axelix.sbs.enabledtrueGlobal switch for the whole starter. Set to false to make every Axelix auto-configuration back off. Behaves identically on the Spring Boot 2, 3, and 4 starters.

Authentication — JWT

PropertyDefaultDescription
axelix.sbs.auth.jwt.algorithm(unset) requiredSigning algorithm. One of HMAC256, HMAC384, or HMAC512. Must match Master's axelix.master.auth.jwt.algorithm.
axelix.sbs.auth.jwt.signing-key(unset) requiredShared secret used to verify Master-issued tokens and to sign self-registration heartbeats. Must match Master's signing key.
axelix.sbs.auth.jwt.duration5mValidity of the self-registration token the starter issues itself. Tokens are rotated automatically before expiry.

Self-registration

Self-registration is off by default (axelix.sbs.discovery.self-registration=false) — leave it that way when Master can find the instance through Master-side autodiscovery instead.

When axelix.sbs.discovery.self-registration=true, the following properties become required:

  • axelix.sbs.discovery.master-url
  • axelix.sbs.discovery.instance-actuator-url
  • axelix.sbs.discovery.instance-name

The Master-side receiver of these heartbeats — endpoint, eviction timeout, eviction sweep schedule — is documented on the Master page in Discovery — self-registration. The JWT signing key configured under axelix.sbs.auth.jwt.signing-key must match axelix.master.auth.jwt.signing-key on Master, otherwise heartbeats are rejected with 401.

PropertyDefaultDescription
axelix.sbs.discovery.self-registrationfalseMaster switch. Set to true to enable self-registration; leave false to rely on Master-side autodiscovery.
axelix.sbs.discovery.master-url(unset) requiredFull URL of Master's self-registration endpoint, e.g. http://master:8080/api/internal/service/register. Required when self-registration=true.
axelix.sbs.discovery.instance-actuator-url(unset) requiredBase URL of this service as reachable from Master (It is necessary to specify the postfix /actuator). Required when self-registration=true.
axelix.sbs.discovery.instance-name(unset) requiredDisplay name shown in Axelix UI and MCP responses. Required when self-registration=true.
axelix.sbs.discovery.heartbeat-interval15sInterval between heartbeats. Should be smaller than Master's eviction heartbeat-timeout.

Endpoint value sanitization

PropertyDefaultDescription
axelix.sbs.endpoints.config.sanitized-properties(empty list)Property keys whose values are masked as ****** for callers without ENV_VALUES_READ (for axelix-env) or CONFIG_PROPS_VALUES_READ (for axelix-configprops). Empty list means all values are masked. See Sanitize sensitive property values for the matching rules.

Transaction monitoring

Transaction monitoring is what powers the Transaction Control page and the related meters: it wraps your @Transactional methods, proxies the data source to count queries, cleans up the per-request transaction stack, and registers the Hibernate N+1 integrator. The collected insights travel to Master inside the instance's registration metadata (exposed through axelix-metadata), so there is no separate actuator endpoint to expose. It is on by default once the starter is on the classpath.

Set axelix.sbs.transaction.monitoring.enabled to false to turn it off entirely — no bean post-processors, no data source proxying, no cleanup filter, and no Hibernate integrator. Use this to shave the associated overhead, to rule out interference while troubleshooting your data source / Hibernate setup, or simply when you don't use the feature.

axelix:
  sbs:
    transaction:
      monitoring:
        enabled: false
PropertyDefaultDescription
axelix.sbs.transaction.monitoring.enabledtrueMaster switch for transaction monitoring. Set to false to make the whole transaction monitoring auto-configuration back off. Behaves identically on the Spring Boot 2, 3, and 4 starters.

Disabling transaction monitoring also disables in-memory pagination detection described below, since that detection is part of the same auto-configuration.

In-memory pagination detection

Detects Hibernate`s in-memory pagination caused by using setFirstResult/setMaxResults together with a collection fetch.

By default, transaction monitoring registers an appender that intercepts Hibernate warnings (HHH000104 in Hibernate 5.x and HHH90003004 in Hibernate 6.x–7.3.x). The starter picks the appender that matches your application's active logging system, so detection works whether you run on Logback or Log4j2:

  • Logback — the starter registers com.axelixlabs.axelix.sbs.spring.core.persistence.hibernate.pagination.LogbackInMemoryPaginationAppender. This is the case for a default Spring Boot setup, where Logback is the logging system.
  • Log4j2 — when your application uses Log4j2 instead (typically after adding spring-boot-starter-log4j2 and excluding the default Logback starter), the starter registers com.axelixlabs.axelix.sbs.spring.core.persistence.hibernate.pagination.Log4j2InMemoryPaginationAppender.

You don't choose between them — the starter detects the active logging system and registers the right appender for you.

Set axelix.sbs.transaction.monitoring.in-memory-pagination-detection.enabled to false if you want to prevent either appender from being registered.

axelix:
  sbs:
    transaction:
      monitoring:
        in-memory-pagination-detection:
          enabled: false

On this page