Application Registration
The Spring Boot Admin Client handles the registration of your application with the Admin Server through the
ApplicationRegistrator and ApplicationFactory interfaces.
ApplicationRegistrator
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();
}
Default Implementation
The DefaultApplicationRegistrator automatically handles:
- Initial registration on application startup
- Periodic re-registration (heartbeat)
- Automatic deregistration on shutdown
- Retry logic for failed registrations
Configuration
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
Registration Process
- 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
ApplicationFactory
The ApplicationFactory is responsible for creating the Application object that contains all registration
information.
public interface ApplicationFactory {
Application createApplication();
}
Default Implementation: DefaultApplicationFactory
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();
}
Application Properties
Name
spring:
boot:
admin:
client:
instance:
name: ${spring.application.name} # Application name
Service URL
The 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
Management URL
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: /actuator
Health URL
Specific health endpoint URL:
spring:
boot:
admin:
client:
instance:
health-url: https://my-app.example.com/actuator/health
Host Type
Control how the service host is determined:
spring:
boot:
admin:
client:
instance:
service-host-type: IP # or CANONICAL
IP: Use the IP addressCANONICAL: Use the canonical hostname
Custom ApplicationFactory
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";
}
}
Specialized ApplicationFactories
Servlet ApplicationFactory
For servlet-based applications:
public class ServletApplicationFactory extends DefaultApplicationFactory {
// Detects servlet port and context path automatically
}
Reactive ApplicationFactory
For WebFlux applications:
public class ReactiveApplicationFactory extends DefaultApplicationFactory {
// Detects Netty port and context automatically
}
Cloud Foundry ApplicationFactory
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.
Application Class
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);
}
}
Building an Application
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();
Registration Lifecycle Events
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");
}
}
Custom Registrator
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;
}
}
Troubleshooting
Registration Fails
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
Instance Not Appearing
Verify:
- Registration returned successfully (check logs)
- Application name is configured
- Health endpoint is accessible from Admin Server
- Actuator endpoints are exposed
Repeated Re-registrations
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
Best Practices
- 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
See Also
- Metadata - Learn about custom metadata
- Service Discovery - Alternative registration using Spring Cloud Discovery
- Client Configuration - Complete configuration reference
- Client Features - Additional client capabilities