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 against2.7.18, Spring Cloud2021.0.9, minimum JDK 11).com.axelixlabs:axelix-spring-boot-3-starter— Spring Boot 3.x (built and tested against3.0.13, Spring Cloud2022.0.4, minimum JDK 17).com.axelixlabs:axelix-spring-boot-4-starter— Spring Boot 4.x (built and tested against4.0.6, Spring Cloud2025.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 byaxelix.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 throughmanagement.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.
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:
| Endpoint | Purpose |
|---|---|
axelix-metadata required | Service metadata; the one Master probes first |
axelix-details | Summary information about the instance |
axelix-beans | Context beans |
axelix-caches | Caches (when a CacheManager is present) |
axelix-conditions | Auto-configuration conditions report |
axelix-configprops | @ConfigurationProperties |
axelix-env | Environment and property sources |
axelix-feign | Feign clients (when Feign is on the classpath) |
axelix-gc | Garbage collection |
axelix-heap-dump | Heap dump |
axelix-loggers | Logging levels |
axelix-metrics | Metrics |
axelix-scheduled-tasks | Scheduled tasks |
axelix-thread-dump | Thread dump |
axelix-dependencies | Dependency 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:
- prometheusThe 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
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-dumpExport 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:
| Meter | Type | Tags | Meaning |
|---|---|---|---|
axelix_transaction_duration | Timer | class, method | Duration of each monitored @Transactional execution. The timer also publishes 0.5, 0.95, and 0.99 percentiles. |
axelix_transaction_queries | Counter | class, method | Total number of SQL queries executed inside monitored transactions. |
axelix_transaction_external_calls | Counter | class, method | Total number of external calls (e.g. RestTemplate) made inside monitored transactions. |
axelix_cache_requests | Counter | cache, result | Total number of cache lookups recorded by Axelix-enhanced caches. |
axelix_cache_enabled | Gauge | cache | Current 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: 5malgorithm 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: 15sA few details that catch people out:
instance-actuator-urlis the base URL of the service as Master will reach it from its own network — host and port only.master-urlis the full URL including/api/internal/service/register. The starter posts to it verbatim.instance-nameis 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.enabledistrueby default), set it tofalseif you want to refuse heartbeats. Master evicts an instance afteraxelix.master.discovery.self-registration.eviction.heartbeat-timeoutof silence (45sby default), so keepheartbeat-intervalcomfortably 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-envandaxelix-configpropsis 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— theENV_VALUES_READauthority lets the caller see raw values.axelix-configprops— theCONFIG_PROPS_VALUES_READauthority 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-keyThe 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
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: falseThe 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.
| Property | Default | Description |
|---|---|---|
axelix.sbs.enabled | true | Global 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
| Property | Default | Description |
|---|---|---|
axelix.sbs.auth.jwt.algorithm | (unset) required | Signing algorithm. One of HMAC256, HMAC384, or HMAC512. Must match Master's axelix.master.auth.jwt.algorithm. |
axelix.sbs.auth.jwt.signing-key | (unset) required | Shared secret used to verify Master-issued tokens and to sign self-registration heartbeats. Must match Master's signing key. |
axelix.sbs.auth.jwt.duration | 5m | Validity 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-urlaxelix.sbs.discovery.instance-actuator-urlaxelix.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.
| Property | Default | Description |
|---|---|---|
axelix.sbs.discovery.self-registration | false | Master switch. Set to true to enable self-registration; leave false to rely on Master-side autodiscovery. |
axelix.sbs.discovery.master-url | (unset) required | Full 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) required | Base 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) required | Display name shown in Axelix UI and MCP responses. Required when self-registration=true. |
axelix.sbs.discovery.heartbeat-interval | 15s | Interval between heartbeats. Should be smaller than Master's eviction heartbeat-timeout. |
Endpoint value sanitization
| Property | Default | Description |
|---|---|---|
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| Property | Default | Description |
|---|---|---|
axelix.sbs.transaction.monitoring.enabled | true | Master 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-log4j2and excluding the default Logback starter), the starter registerscom.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: falseRelated
- Configuring the build plugin — the second half of wiring a service up; required for the instance to register.
- Configuring Master — where the signing key, eviction timeout, and Kubernetes scan are set.
- What is Master? — background on how Master uses the data the starter exposes.
- Authentication — deeper look at JWT and authority resolution on both sides.