| sidebar_position | 20 | ||
|---|---|---|---|
| sidebar_custom_props |
|
The Spring Boot Admin Client handles the registration of your application with the Admin Server through the
ApplicationRegistrator and ApplicationFactory interfaces.
The ApplicationRegistrator is responsible for managing the registration lifecycle:
public interface ApplicationRegistrator {
/**
* Registers the client application at spring-boot-admin-server.
* @return true if successful registration on at least one admin server
*/
boolean register();
/**
* Tries to deregister currently registered application
*/
void deregister();
/**
* @return the id of this client as given by the admin server.
* Returns null if not registered yet.
*/
String getRegisteredId();
}The DefaultApplicationRegistrator automatically handles:
- Initial registration on application startup
- Periodic re-registration (heartbeat)
- Automatic deregistration on shutdown
- Retry logic for failed registrations
spring:
boot:
admin:
client:
url: http://localhost:8080 # Admin Server URL
period: 10000 # Registration interval in milliseconds
auto-registration: true # Enable auto-registration
auto-deregistration: true # Enable auto-deregistration on shutdown- Application Startup: The
RegistrationApplicationListenertriggers registration whenWebServerInitializedEventis fired - Create Application:
ApplicationFactorycreates the registration payload - HTTP POST: Client sends POST request to
/instancesendpoint - Receive ID: Server responds with an instance ID
- Periodic Heartbeat: Client re-registers at configured intervals
- Shutdown Hook: Application deregisters on graceful shutdown
The ApplicationFactory is responsible for creating the Application object that contains all registration
information.
public interface ApplicationFactory {
Application createApplication();
}The default factory gathers information from:
InstanceProperties- Client configurationServerProperties- Web server configurationManagementServerProperties- Actuator configurationPathMappedEndpoints- Actuator endpoint mappingsMetadataContributor- Custom metadata
@Override
public Application createApplication() {
return Application.create(getName())
.healthUrl(getHealthUrl())
.managementUrl(getManagementUrl())
.serviceUrl(getServiceUrl())
.metadata(getMetadata())
.build();
}spring:
boot:
admin:
client:
instance:
name: ${spring.application.name} # Application nameThe URL where your application can be accessed:
spring:
boot:
admin:
client:
instance:
service-url: https://my-app.example.com
# or let it auto-detect:
service-base-url: https://my-app.example.com
service-path: /Auto-detection uses:
- Configured
service-url(highest priority) service-base-url+service-path- Auto-detected from server properties
URL for actuator endpoints:
spring:
boot:
admin:
client:
instance:
management-url: https://my-app.example.com/actuator
# or
management-base-url: https://my-app.example.com
management:
endpoints:
web:
base-path: /actuatorSpecific health endpoint URL:
spring:
boot:
admin:
client:
instance:
health-url: https://my-app.example.com/actuator/healthControl how the service host is determined:
spring:
boot:
admin:
client:
instance:
service-host-type: IP # or CANONICALIP: Use the IP addressCANONICAL: Use the canonical hostname
Create a custom factory for specialized registration logic:
@Component
public class CustomApplicationFactory implements ApplicationFactory {
private final InstanceProperties instance;
private final Environment environment;
public CustomApplicationFactory(InstanceProperties instance,
Environment environment) {
this.instance = instance;
this.environment = environment;
}
@Override
public Application createApplication() {
Map<String, String> metadata = new HashMap<>();
metadata.put("environment", environment.getProperty("app.environment"));
metadata.put("version", environment.getProperty("app.version"));
metadata.put("region", environment.getProperty("cloud.region"));
return Application.create(instance.getName())
.healthUrl(buildHealthUrl())
.managementUrl(buildManagementUrl())
.serviceUrl(buildServiceUrl())
.metadata(metadata)
.build();
}
private String buildHealthUrl() {
// Custom logic to build health URL
return "https://my-app.com/health";
}
private String buildManagementUrl() {
// Custom logic to build management URL
return "https://my-app.com/management";
}
private String buildServiceUrl() {
// Custom logic to build service URL
return "https://my-app.com";
}
}For servlet-based applications:
public class ServletApplicationFactory extends DefaultApplicationFactory {
// Detects servlet port and context path automatically
}For WebFlux applications:
public class ReactiveApplicationFactory extends DefaultApplicationFactory {
// Detects Netty port and context automatically
}For Cloud Foundry deployments:
public class CloudFoundryApplicationFactory implements ApplicationFactory {
// Uses CF-specific environment variables:
// - vcap.application.application_id
// - vcap.application.instance_id
// - vcap.application.uris
}Automatically activated when Cloud Foundry is detected.
The Application class represents the registration payload:
public class Application {
private final String name;
private final String managementUrl;
private final String healthUrl;
private final String serviceUrl;
private final Map<String, String> metadata;
// Builder pattern
public static Builder create(String name) {
return new Builder(name);
}
}Application app = Application.create("my-application")
.healthUrl("http://localhost:8080/actuator/health")
.managementUrl("http://localhost:8080/actuator")
.serviceUrl("http://localhost:8080")
.metadata("version", "1.0.0")
.metadata("environment", "production")
.build();Spring Boot Admin Client fires application events during registration:
@Component
public class RegistrationEventListener {
@EventListener
public void onRegistration(InstanceRegisteredEvent event) {
String instanceId = event.getRegistration().getInstanceId();
log.info("Registered with instance ID: {}", instanceId);
}
@EventListener
public void onDeregistration(InstanceDeregisteredEvent event) {
log.info("Deregistered instance");
}
}Implement custom registration logic:
@Component
public class CustomApplicationRegistrator implements ApplicationRegistrator {
private final ApplicationFactory applicationFactory;
private final RestClient restClient;
private final String adminUrl;
private volatile String registeredId;
@Override
public boolean register() {
Application application = applicationFactory.createApplication();
try {
Map<String, Object> response = restClient.post()
.uri(adminUrl + "/instances")
.body(application)
.retrieve()
.body(new ParameterizedTypeReference<Map<String, Object>>() {});
this.registeredId = (String) response.get("id");
log.info("Registered as: {}", registeredId);
return true;
} catch (Exception e) {
log.error("Registration failed", e);
return false;
}
}
@Override
public void deregister() {
if (registeredId != null) {
try {
restClient.delete()
.uri(adminUrl + "/instances/" + registeredId)
.retrieve()
.toBodilessEntity();
log.info("Deregistered successfully");
} catch (Exception e) {
log.error("Deregistration failed", e);
}
}
}
@Override
public String getRegisteredId() {
return registeredId;
}
}Check:
- Admin Server URL is correct and accessible
- Network connectivity between client and server
- Firewall rules allow outbound connections
- Admin Server is running and healthy
- Credentials are correct if security is enabled
Verify:
- Registration returned successfully (check logs)
- Application name is configured
- Health endpoint is accessible from Admin Server
- Actuator endpoints are exposed
This is normal behavior - the client re-registers periodically as a heartbeat. Adjust the period if needed:
spring:
boot:
admin:
client:
period: 30000 # 30 seconds instead of default 10- Use environment-specific URLs for service URL in different environments
- Configure appropriate metadata to help identify instances
- Set reasonable registration periods - too frequent causes unnecessary load
- Enable auto-deregistration for clean shutdown
- Use service discovery for dynamic environments instead of direct client registration
- Monitor registration logs to ensure successful registration
- Configure health check paths correctly for proper monitoring
- Metadata - Learn about custom metadata
- Service Discovery - Alternative registration using Spring Cloud Discovery
- Client Configuration - Complete configuration reference
- Client Features - Additional client capabilities