From 9212fb99b92c5b7feb0e02c41ed41b041ce84cb3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Mar 2026 13:40:03 +0000 Subject: [PATCH 1/7] Initial plan From 8edf288eb94b7fe3796fcf89f21cb15ee661d477 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Mar 2026 13:50:08 +0000 Subject: [PATCH 2/7] Add JavaDoc comments with Example Usage sections to discovery client classes Add JavaDoc to non-private methods missing documentation in: - ReactiveDiscoveryClientAdapter: constructor, description(), getInstances(), getServices(), probe(), getOrder() - UnionDiscoveryClient: description(), getInstances(), getServices(), getDiscoveryClients(), getOrder(), afterSingletonsInstantiated(), destroy(), setApplicationContext() - DiscoveryClientAutoConfiguration: unionDiscoveryClient() bean method - ReactiveDiscoveryClientAutoConfiguration: reactiveDiscoveryClientAdapter() bean method Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../ReactiveDiscoveryClientAdapter.java | 35 +++++++++++++++ .../discovery/UnionDiscoveryClient.java | 44 +++++++++++++++++++ .../DiscoveryClientAutoConfiguration.java | 13 ++++++ ...ctiveDiscoveryClientAutoConfiguration.java | 14 ++++++ 4 files changed, 106 insertions(+) diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/ReactiveDiscoveryClientAdapter.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/ReactiveDiscoveryClientAdapter.java index 652ca766..73ba2fe2 100644 --- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/ReactiveDiscoveryClientAdapter.java +++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/ReactiveDiscoveryClientAdapter.java @@ -39,32 +39,67 @@ public class ReactiveDiscoveryClientAdapter implements DiscoveryClient { private final ReactiveDiscoveryClient reactiveDiscoveryClient; + /** + * Create a new {@link ReactiveDiscoveryClientAdapter} that wraps the given + * {@link ReactiveDiscoveryClient} as a blocking {@link DiscoveryClient}. + * + *
Example Usage: + *
{@code
+ * ReactiveDiscoveryClient reactiveClient = new SimpleReactiveDiscoveryClient(properties);
+ * DiscoveryClient adapter = new ReactiveDiscoveryClientAdapter(reactiveClient);
+ * List services = adapter.getServices();
+ * }
+ *
+ * @param reactiveDiscoveryClient the {@link ReactiveDiscoveryClient} to adapt, must not be {@code null}
+ */
public ReactiveDiscoveryClientAdapter(ReactiveDiscoveryClient reactiveDiscoveryClient) {
this.reactiveDiscoveryClient = reactiveDiscoveryClient;
}
+ /**
+ * {@inheritDoc}
+ * Delegates to the underlying {@link ReactiveDiscoveryClient#description()}. + */ @Override public String description() { return this.reactiveDiscoveryClient.description(); } + /** + * {@inheritDoc} + *
Delegates to {@link ReactiveDiscoveryClient#getInstances(String)} and collects the
+ * reactive {@link Flux} result into a blocking {@link List}.
+ */
@Override
public List Delegates to {@link ReactiveDiscoveryClient#getServices()} and collects the
+ * reactive {@link Flux} result into a blocking {@link List}.
+ */
@Override
public List Delegates to {@link ReactiveDiscoveryClient#probe()}.
+ */
@Override
public void probe() {
this.reactiveDiscoveryClient.probe();
}
+ /**
+ * {@inheritDoc}
+ * Delegates to {@link ReactiveDiscoveryClient#getOrder()}.
+ */
@Override
public int getOrder() {
return this.reactiveDiscoveryClient.getOrder();
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/UnionDiscoveryClient.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/UnionDiscoveryClient.java
index 944f0cdd..8b19619c 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/UnionDiscoveryClient.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/UnionDiscoveryClient.java
@@ -48,11 +48,20 @@ public final class UnionDiscoveryClient implements DiscoveryClient, ApplicationC
private List Aggregates service instances from all underlying {@link DiscoveryClient DiscoveryClients}.
+ */
@Override
public List Returns a deduplicated union of service names from all underlying {@link DiscoveryClient DiscoveryClients}.
+ */
@Override
public List Example Usage:
+ * Eagerly initializes the list of {@link DiscoveryClient DiscoveryClients} after all singletons are instantiated.
+ */
@Override
public void afterSingletonsInstantiated() {
this.discoveryClients = getDiscoveryClients();
}
+ /**
+ * {@inheritDoc}
+ * Clears the cached list of {@link DiscoveryClient DiscoveryClients} on bean destruction.
+ */
@Override
public void destroy() throws Exception {
this.discoveryClients.clear();
}
+ /**
+ * {@inheritDoc}
+ * Stores the {@link ApplicationContext} used to look up {@link DiscoveryClient} beans.
+ */
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/autoconfigure/DiscoveryClientAutoConfiguration.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/autoconfigure/DiscoveryClientAutoConfiguration.java
index 28f9b1e7..7fc2c6eb 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/autoconfigure/DiscoveryClientAutoConfiguration.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/autoconfigure/DiscoveryClientAutoConfiguration.java
@@ -80,6 +80,19 @@ public class DiscoveryClientAutoConfiguration {
@ConditionalOnProperty(name = DISCOVERY_CLIENT_MODE_PROPERTY_NAME, havingValue = UNION_DISCOVERY_CLIENT_MODE)
public static class UnionConfiguration {
+ /**
+ * Creates a {@link UnionDiscoveryClient} bean that aggregates all {@link DiscoveryClient}
+ * instances in the {@link org.springframework.context.ApplicationContext}.
+ *
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Returns an empty string as WebFlux applications do not use a servlet context path.
+ *
+ * Example Usage:
+ * Always returns {@code false} for WebFlux applications, as no mappings are excluded.
+ *
+ * Example Usage:
+ * Returns the servlet context path configured via {@code server.servlet.context-path}.
+ *
+ * Example Usage:
+ * Excludes built-in Spring filter mappings and the default DispatcherServlet mapping.
+ *
+ * Example Usage:
+ * Example Usage:
+ * Initializes the {@link Registration}, {@link ServiceRegistry}, and
+ * {@link AbstractAutoServiceRegistration} from available bean providers.
+ *
+ * Example Usage:
+ * Captures the web server port and detects the running state of the
+ * {@link AbstractAutoServiceRegistration}.
+ *
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * Example Usage:
+ * {@code
+ * UnionDiscoveryClient unionClient = applicationContext.getBean(UnionDiscoveryClient.class);
+ * List
+ *
+ * @return an unmodifiable list of {@link DiscoveryClient} instances
+ */
public List{@code
+ * // Activated when microsphere.spring.cloud.client.discovery.mode=union
+ * UnionDiscoveryClient client = applicationContext.getBean(UnionDiscoveryClient.class);
+ * List
+ *
+ * @return a new {@link UnionDiscoveryClient} instance
+ */
@Bean
public UnionDiscoveryClient unionDiscoveryClient() {
return new UnionDiscoveryClient();
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/autoconfigure/ReactiveDiscoveryClientAutoConfiguration.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/autoconfigure/ReactiveDiscoveryClientAutoConfiguration.java
index 26aa7b18..8cb3a906 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/autoconfigure/ReactiveDiscoveryClientAutoConfiguration.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/autoconfigure/ReactiveDiscoveryClientAutoConfiguration.java
@@ -61,6 +61,20 @@ public class ReactiveDiscoveryClientAutoConfiguration {
@ConditionalOnBlockingDiscoveryEnabled
public static class BlockingConfiguration {
+ /**
+ * Creates a {@link ReactiveDiscoveryClientAdapter} bean that adapts a
+ * {@link ReactiveDiscoveryClient} to the blocking {@link org.springframework.cloud.client.discovery.DiscoveryClient} interface.
+ *
+ * {@code
+ * // Auto-configured when both reactive and blocking discovery are enabled
+ * DiscoveryClient client = applicationContext.getBean(ReactiveDiscoveryClientAdapter.class);
+ * List
+ *
+ * @param reactiveDiscoveryClient the {@link ReactiveDiscoveryClient} to adapt
+ * @return a new {@link ReactiveDiscoveryClientAdapter} instance
+ */
@Bean
@ConditionalOnBean(ReactiveDiscoveryClient.class)
public ReactiveDiscoveryClientAdapter reactiveDiscoveryClientAdapter(ReactiveDiscoveryClient reactiveDiscoveryClient) {
From 59def04f14a4f107e2b80d28d07f98fa9f70a859 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 21 Mar 2026 13:55:31 +0000
Subject: [PATCH 3/7] Add JavaDoc comments with Example Usage sections to
non-private methods
Add comprehensive JavaDoc documentation to non-private methods that were
missing it in the service registry package:
- InMemoryServiceRegistry: all @Override methods and getMetadata()
- MultipleAutoServiceRegistration: constructor and all @Override methods
- MultipleRegistration: constructor, all @Override methods, getDefaultRegistration(), special()
- MultipleServiceRegistry: constructor, all @Override methods, getRegistrationClass()
- RegistrationMetaData: constructor and all Map @Override methods
- SimpleAutoServiceRegistration: constructor and all @Override methods
- SimpleServiceRegistry: all constructors, @Override methods, and package-private getInstances()
Each JavaDoc includes:
- Brief description with {@link} cross-references
- Example Usage section with {@code ...} blocks
- @param, @return tags where applicable
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
.../registry/InMemoryServiceRegistry.java | 78 +++++++++
.../MultipleAutoServiceRegistration.java | 65 +++++++
.../registry/MultipleRegistration.java | 120 +++++++++++++
.../registry/MultipleServiceRegistry.java | 96 ++++++++++
.../registry/RegistrationMetaData.java | 164 ++++++++++++++++++
.../SimpleAutoServiceRegistration.java | 64 +++++++
.../registry/SimpleServiceRegistry.java | 126 ++++++++++++++
7 files changed, 713 insertions(+)
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/InMemoryServiceRegistry.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/InMemoryServiceRegistry.java
index 26da337e..7d1840c3 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/InMemoryServiceRegistry.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/InMemoryServiceRegistry.java
@@ -35,23 +35,73 @@ public class InMemoryServiceRegistry implements ServiceRegistry {
private final ConcurrentMap{@code
+ * InMemoryServiceRegistry registry = new InMemoryServiceRegistry();
+ * Registration registration = createRegistration();
+ * registry.register(registration);
+ * }
+ *
+ * @param registration the {@link Registration} to store
+ */
@Override
public void register(Registration registration) {
String id = registration.getInstanceId();
storage.put(id, registration);
}
+ /**
+ * Removes the given {@link Registration} instance from the in-memory storage.
+ *
+ * {@code
+ * InMemoryServiceRegistry registry = new InMemoryServiceRegistry();
+ * Registration registration = createRegistration();
+ * registry.register(registration);
+ * registry.deregister(registration);
+ * }
+ *
+ * @param registration the {@link Registration} to remove
+ */
@Override
public void deregister(Registration registration) {
String id = registration.getInstanceId();
storage.remove(id, registration);
}
+ /**
+ * Closes this registry by clearing all stored {@link Registration} instances.
+ *
+ * {@code
+ * InMemoryServiceRegistry registry = new InMemoryServiceRegistry();
+ * registry.register(registration);
+ * registry.close();
+ * }
+ */
@Override
public void close() {
storage.clear();
}
+ /**
+ * Sets the status of the given {@link Registration} by storing it in
+ * the registration's metadata under the {@code _status_} key.
+ *
+ * {@code
+ * InMemoryServiceRegistry registry = new InMemoryServiceRegistry();
+ * registry.register(registration);
+ * registry.setStatus(registration, "UP");
+ * }
+ *
+ * @param registration the {@link Registration} whose status is to be set
+ * @param status the status value to set
+ */
@Override
public void setStatus(Registration registration, String status) {
Map{@code
+ * InMemoryServiceRegistry registry = new InMemoryServiceRegistry();
+ * registry.register(registration);
+ * registry.setStatus(registration, "UP");
+ * Object status = registry.getStatus(registration); // "UP"
+ * }
+ *
+ * @param registration the {@link Registration} whose status is to be retrieved
+ * @return the status value, or {@code null} if not set or registration not found
+ */
@Override
public Object getStatus(Registration registration) {
Map{@code
+ * InMemoryServiceRegistry registry = new InMemoryServiceRegistry();
+ * registry.register(registration);
+ * Map
+ *
+ * @param registration the {@link Registration} whose metadata is to be retrieved
+ * @return the metadata map, or {@code null} if the registration is not found
+ */
protected Map{@code
+ * MultipleRegistration registration = new MultipleRegistration(registrations);
+ * ServiceRegistry
+ *
+ * @param multipleRegistration the {@link MultipleRegistration} to manage
+ * @param serviceRegistry the {@link ServiceRegistry} to delegate to
+ * @param properties the {@link AutoServiceRegistrationProperties} for configuration
+ */
public MultipleAutoServiceRegistration(MultipleRegistration multipleRegistration,
ServiceRegistry{@code
+ * MultipleAutoServiceRegistration autoReg = ...;
+ * Object config = autoReg.getConfiguration(); // null
+ * }
+ *
+ * @return {@code null}
+ */
@Override
protected Object getConfiguration() {
return null;
}
+ /**
+ * Determines whether this auto service registration is enabled based on the
+ * {@link AutoServiceRegistrationProperties}.
+ *
+ * {@code
+ * MultipleAutoServiceRegistration autoReg = ...;
+ * boolean enabled = autoReg.isEnabled();
+ * }
+ *
+ * @return {@code true} if auto service registration is enabled
+ */
@Override
protected boolean isEnabled() {
return this.autoServiceRegistrationProperties.isEnabled();
}
+ /**
+ * Returns the {@link MultipleRegistration} managed by this auto service registration.
+ *
+ * {@code
+ * MultipleAutoServiceRegistration autoReg = ...;
+ * MultipleRegistration registration = autoReg.getRegistration();
+ * }
+ *
+ * @return the {@link MultipleRegistration} instance
+ */
@Override
protected MultipleRegistration getRegistration() {
return this.multipleRegistration;
}
+ /**
+ * Returns the management {@link MultipleRegistration}, which is the same as
+ * the primary registration in this implementation.
+ *
+ * {@code
+ * MultipleAutoServiceRegistration autoReg = ...;
+ * MultipleRegistration mgmtRegistration = autoReg.getManagementRegistration();
+ * }
+ *
+ * @return the {@link MultipleRegistration} instance used for management
+ */
@Override
protected MultipleRegistration getManagementRegistration() {
return this.multipleRegistration;
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/MultipleRegistration.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/MultipleRegistration.java
index 23783914..aba1ff63 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/MultipleRegistration.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/MultipleRegistration.java
@@ -29,6 +29,21 @@ public class MultipleRegistration implements Registration {
private final RegistrationMetaData metaData;
+ /**
+ * Constructs a new {@link MultipleRegistration} from the given collection of
+ * {@link Registration} instances. The last registration in the collection becomes
+ * the default registration.
+ *
+ * {@code
+ * DefaultRegistration registration = new DefaultRegistration();
+ * registration.setServiceId("test-service");
+ * MultipleRegistration multipleRegistration =
+ * new MultipleRegistration(List.of(registration));
+ * }
+ *
+ * @param registrations the collection of {@link Registration} instances, must not be empty
+ */
public MultipleRegistration(Collection{@code
+ * MultipleRegistration multipleRegistration = new MultipleRegistration(registrations);
+ * String instanceId = multipleRegistration.getInstanceId();
+ * }
+ *
+ * @return the instance ID of the default registration
+ */
@Override
public String getInstanceId() {
return getDefaultRegistration().getInstanceId();
}
+ /**
+ * Returns the service ID from the default {@link Registration}.
+ *
+ * {@code
+ * MultipleRegistration multipleRegistration = new MultipleRegistration(registrations);
+ * String serviceId = multipleRegistration.getServiceId();
+ * }
+ *
+ * @return the service ID of the default registration
+ */
@Override
public String getServiceId() {
return getDefaultRegistration().getServiceId();
}
+ /**
+ * Returns the host from the default {@link Registration}.
+ *
+ * {@code
+ * MultipleRegistration multipleRegistration = new MultipleRegistration(registrations);
+ * String host = multipleRegistration.getHost();
+ * }
+ *
+ * @return the host of the default registration
+ */
@Override
public String getHost() {
return getDefaultRegistration().getHost();
}
+ /**
+ * Returns the port from the default {@link Registration}.
+ *
+ * {@code
+ * MultipleRegistration multipleRegistration = new MultipleRegistration(registrations);
+ * int port = multipleRegistration.getPort();
+ * }
+ *
+ * @return the port of the default registration
+ */
@Override
public int getPort() {
return getDefaultRegistration().getPort();
}
+ /**
+ * Returns whether the default {@link Registration} is secure.
+ *
+ * {@code
+ * MultipleRegistration multipleRegistration = new MultipleRegistration(registrations);
+ * boolean secure = multipleRegistration.isSecure();
+ * }
+ *
+ * @return {@code true} if the default registration is secure
+ */
@Override
public boolean isSecure() {
return getDefaultRegistration().isSecure();
}
+ /**
+ * Returns the {@link URI} from the default {@link Registration}.
+ *
+ * {@code
+ * MultipleRegistration multipleRegistration = new MultipleRegistration(registrations);
+ * URI uri = multipleRegistration.getUri();
+ * }
+ *
+ * @return the URI of the default registration
+ */
@Override
public URI getUri() {
return getDefaultRegistration().getUri();
}
+ /**
+ * Returns the aggregated {@link RegistrationMetaData} that synchronizes metadata
+ * across all underlying {@link Registration} instances.
+ *
+ * {@code
+ * MultipleRegistration multipleRegistration = new MultipleRegistration(registrations);
+ * Map
+ *
+ * @return the aggregated metadata map
+ */
@Override
public Map{@code
+ * MultipleRegistration multipleRegistration = new MultipleRegistration(registrations);
+ * Registration defaultReg = multipleRegistration.getDefaultRegistration();
+ * }
+ *
+ * @return the default {@link Registration}
+ */
public Registration getDefaultRegistration() {
return defaultRegistration;
}
+ /**
+ * Retrieves a specific {@link Registration} by its class type. If the specified
+ * class is {@link Registration} itself, returns this {@link MultipleRegistration}.
+ *
+ * {@code
+ * MultipleRegistration multipleRegistration = new MultipleRegistration(registrations);
+ * DefaultRegistration specific = multipleRegistration.special(DefaultRegistration.class);
+ * Registration self = multipleRegistration.special(Registration.class);
+ * }
+ *
+ * @param specialClass the specific {@link Registration} subclass to look up
+ * @param {@code
+ * ServiceRegistry
+ *
+ * @param registriesMap the map of Spring bean names to {@link ServiceRegistry} instances,
+ * must not be empty
+ */
public MultipleServiceRegistry(Map{@code
+ * MultipleServiceRegistry registry = new MultipleServiceRegistry(registriesMap);
+ * MultipleRegistration registration = new MultipleRegistration(registrations);
+ * registry.register(registration);
+ * }
+ *
+ * @param registration the {@link MultipleRegistration} to register
+ */
@Override
public void register(MultipleRegistration registration) {
iterate(registration, (reg, registry) -> registry.register(reg));
}
+ /**
+ * Deregisters the given {@link MultipleRegistration} by delegating to each underlying
+ * {@link ServiceRegistry} with the corresponding specific {@link Registration}.
+ *
+ * {@code
+ * MultipleServiceRegistry registry = new MultipleServiceRegistry(registriesMap);
+ * MultipleRegistration registration = new MultipleRegistration(registrations);
+ * registry.register(registration);
+ * registry.deregister(registration);
+ * }
+ *
+ * @param registration the {@link MultipleRegistration} to deregister
+ */
@Override
public void deregister(MultipleRegistration registration) {
iterate(registration, (reg, registry) -> registry.deregister(reg));
}
+ /**
+ * Closes all underlying {@link ServiceRegistry} instances.
+ *
+ * {@code
+ * MultipleServiceRegistry registry = new MultipleServiceRegistry(registriesMap);
+ * registry.close();
+ * }
+ */
@Override
public void close() {
iterate(ServiceRegistry::close);
}
+ /**
+ * Sets the status of the given {@link MultipleRegistration} by delegating to each
+ * underlying {@link ServiceRegistry} with the corresponding specific {@link Registration}.
+ *
+ * {@code
+ * MultipleServiceRegistry registry = new MultipleServiceRegistry(registriesMap);
+ * registry.register(registration);
+ * registry.setStatus(registration, "UP");
+ * }
+ *
+ * @param registration the {@link MultipleRegistration} whose status is to be set
+ * @param status the status value to set
+ */
@Override
public void setStatus(MultipleRegistration registration, String status) {
iterate(registration, (reg, registry) -> registry.setStatus(reg, status));
@@ -87,6 +152,22 @@ private void iterate(Consumer{@code
+ * MultipleServiceRegistry registry = new MultipleServiceRegistry(registriesMap);
+ * registry.register(registration);
+ * registry.setStatus(registration, "UP");
+ * Object status = registry.getStatus(registration); // "UP"
+ * }
+ *
+ * @param registration the {@link MultipleRegistration} whose status is to be retrieved
+ * @param {@code
+ * Class extends Registration> regClass =
+ * MultipleServiceRegistry.getRegistrationClass(NacosServiceRegistry.class);
+ * // returns NacosRegistration.class
+ * }
+ *
+ * @param serviceRegistryClass the {@link ServiceRegistry} implementation class
+ * @return the resolved {@link Registration} subclass
+ */
static Class extends Registration> getRegistrationClass(Class> serviceRegistryClass) {
Class> registrationClass = forClass(serviceRegistryClass)
.as(ServiceRegistry.class)
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/RegistrationMetaData.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/RegistrationMetaData.java
index 6cab1bc0..638acce7 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/RegistrationMetaData.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/RegistrationMetaData.java
@@ -40,6 +40,20 @@ public final class RegistrationMetaData implements Map{@code
+ * DefaultRegistration registration = new DefaultRegistration();
+ * registration.getMetadata().put("key1", "value1");
+ * RegistrationMetaData metaData = new RegistrationMetaData(List.of(registration));
+ * }
+ *
+ * @param registrations the collection of {@link Registration} instances, must not be empty
+ */
public RegistrationMetaData(Collection{@code
+ * RegistrationMetaData metaData = new RegistrationMetaData(registrations);
+ * int count = metaData.size(); // e.g. 3
+ * }
+ *
+ * @return the number of key-value mappings in this metadata
+ */
@Override
public int size() {
return applicationMetaData.size();
}
+ /**
+ * Returns whether this metadata map is empty.
+ *
+ * {@code
+ * RegistrationMetaData metaData = new RegistrationMetaData(registrations);
+ * boolean empty = metaData.isEmpty(); // false if registrations have metadata
+ * }
+ *
+ * @return {@code true} if this metadata contains no entries
+ */
@Override
public boolean isEmpty() {
return this.applicationMetaData.isEmpty();
}
+ /**
+ * Returns whether this metadata contains the specified key.
+ *
+ * {@code
+ * RegistrationMetaData metaData = new RegistrationMetaData(registrations);
+ * boolean hasKey = metaData.containsKey("key1"); // true
+ * boolean missing = metaData.containsKey("unknown"); // false
+ * }
+ *
+ * @param key the key to check for
+ * @return {@code true} if this metadata contains the specified key
+ */
@Override
public boolean containsKey(Object key) {
return this.applicationMetaData.containsKey(key);
}
+ /**
+ * Returns whether this metadata contains the specified value.
+ *
+ * {@code
+ * RegistrationMetaData metaData = new RegistrationMetaData(registrations);
+ * boolean hasValue = metaData.containsValue("value1"); // true
+ * boolean missing = metaData.containsValue("unknown"); // false
+ * }
+ *
+ * @param value the value to check for
+ * @return {@code true} if this metadata contains the specified value
+ */
@Override
public boolean containsValue(Object value) {
return this.applicationMetaData.containsValue(value);
}
+ /**
+ * Returns the metadata value associated with the specified key.
+ *
+ * {@code
+ * RegistrationMetaData metaData = new RegistrationMetaData(registrations);
+ * String value = metaData.get("key1"); // "value1"
+ * String missing = metaData.get("unknown"); // null
+ * }
+ *
+ * @param key the key whose associated value is to be returned
+ * @return the value associated with the key, or {@code null} if not found
+ */
@Override
public String get(Object key) {
return this.applicationMetaData.get(key);
}
+ /**
+ * Puts a metadata entry and synchronizes it across all underlying {@link Registration}
+ * instances.
+ *
+ * {@code
+ * RegistrationMetaData metaData = new RegistrationMetaData(registrations);
+ * metaData.put("key4", "value4");
+ * String value = metaData.get("key4"); // "value4"
+ * }
+ *
+ * @param key the metadata key
+ * @param value the metadata value
+ * @return the previous value associated with the key, or {@code null}
+ */
@Override
public String put(String key, String value) {
synchronized (lock) {
@@ -94,6 +184,20 @@ public String put(String key, String value) {
return this.applicationMetaData.put(key, value);
}
+ /**
+ * Removes the metadata entry for the specified key and synchronizes the removal
+ * across all underlying {@link Registration} instances.
+ *
+ * {@code
+ * RegistrationMetaData metaData = new RegistrationMetaData(registrations);
+ * metaData.remove("key1");
+ * String value = metaData.get("key1"); // null
+ * }
+ *
+ * @param key the key whose mapping is to be removed
+ * @return the previous value associated with the key, or {@code null}
+ */
@Override
public String remove(Object key) {
synchronized (lock) {
@@ -104,6 +208,18 @@ public String remove(Object key) {
return this.applicationMetaData.remove(key);
}
+ /**
+ * Copies all entries from the specified map into this metadata and synchronizes
+ * them across all underlying {@link Registration} instances.
+ *
+ * {@code
+ * RegistrationMetaData metaData = new RegistrationMetaData(registrations);
+ * metaData.putAll(Map.of("key4", "value4", "key5", "value5"));
+ * }
+ *
+ * @param m the map of entries to add
+ */
@Override
public void putAll(Map extends String, ? extends String> m) {
synchronized (lock) {
@@ -114,6 +230,17 @@ public void putAll(Map extends String, ? extends String> m) {
this.applicationMetaData.putAll(m);
}
+ /**
+ * Clears all metadata entries and synchronizes the clearing across all underlying
+ * {@link Registration} instances.
+ *
+ * {@code
+ * RegistrationMetaData metaData = new RegistrationMetaData(registrations);
+ * metaData.clear();
+ * int size = metaData.size(); // 0
+ * }
+ */
@Override
public void clear() {
synchronized (lock) {
@@ -122,16 +249,53 @@ public void clear() {
this.applicationMetaData.clear();
}
+ /**
+ * Returns an unmodifiable {@link Set} view of the metadata keys.
+ *
+ * {@code
+ * RegistrationMetaData metaData = new RegistrationMetaData(registrations);
+ * Set
+ *
+ * @return an unmodifiable set of metadata keys
+ */
@Override
public Set{@code
+ * RegistrationMetaData metaData = new RegistrationMetaData(registrations);
+ * Collection
+ *
+ * @return an unmodifiable collection of metadata values
+ */
@Override
public Collection{@code
+ * RegistrationMetaData metaData = new RegistrationMetaData(registrations);
+ * Set
+ *
+ * @return a set of metadata entries
+ */
@Override
public Set{@code
+ * InMemoryServiceRegistry serviceRegistry = new InMemoryServiceRegistry();
+ * AutoServiceRegistrationProperties properties = new AutoServiceRegistrationProperties();
+ * Registration registration = createRegistration();
+ * SimpleAutoServiceRegistration autoReg =
+ * new SimpleAutoServiceRegistration(serviceRegistry, properties, registration);
+ * }
+ *
+ * @param serviceRegistry the {@link ServiceRegistry} to delegate to
+ * @param properties the {@link AutoServiceRegistrationProperties} for configuration
+ * @param registration the {@link Registration} to manage
+ */
public SimpleAutoServiceRegistration(ServiceRegistry{@code
+ * SimpleAutoServiceRegistration autoReg = ...;
+ * Object config = autoReg.getConfiguration();
+ * }
+ *
+ * @return the {@link AutoServiceRegistrationProperties} instance
+ */
@Override
protected Object getConfiguration() {
return properties;
}
+ /**
+ * Determines whether this auto service registration is enabled based on the
+ * {@link AutoServiceRegistrationProperties}.
+ *
+ * {@code
+ * SimpleAutoServiceRegistration autoReg = ...;
+ * boolean enabled = autoReg.isEnabled();
+ * }
+ *
+ * @return {@code true} if auto service registration is enabled
+ */
@Override
protected boolean isEnabled() {
return properties.isEnabled();
}
+ /**
+ * Returns the {@link Registration} managed by this auto service registration.
+ *
+ * {@code
+ * SimpleAutoServiceRegistration autoReg = ...;
+ * Registration registration = autoReg.getRegistration();
+ * }
+ *
+ * @return the {@link Registration} instance
+ */
@Override
protected Registration getRegistration() {
return registration;
}
+ /**
+ * Returns the management {@link Registration}, which is the same as the primary
+ * registration in this implementation.
+ *
+ * {@code
+ * SimpleAutoServiceRegistration autoReg = ...;
+ * Registration mgmtRegistration = autoReg.getManagementRegistration();
+ * }
+ *
+ * @return the {@link Registration} instance used for management
+ */
@Override
protected Registration getManagementRegistration() {
return registration;
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/SimpleServiceRegistry.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/SimpleServiceRegistry.java
index 6d90e12b..386bd33c 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/SimpleServiceRegistry.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/SimpleServiceRegistry.java
@@ -48,48 +48,174 @@ public class SimpleServiceRegistry implements ServiceRegistry{@code
+ * SimpleDiscoveryProperties properties = new SimpleDiscoveryProperties();
+ * SimpleServiceRegistry registry = new SimpleServiceRegistry(properties);
+ * }
+ *
+ * @param properties the {@link SimpleDiscoveryProperties} to use
+ */
public SimpleServiceRegistry(SimpleDiscoveryProperties properties) {
this(getInstancesMap(properties));
}
+ /**
+ * Constructs a new {@link SimpleServiceRegistry} using the given
+ * {@link SimpleReactiveDiscoveryProperties} to obtain the instances map.
+ *
+ * {@code
+ * SimpleReactiveDiscoveryProperties reactiveProperties = ...;
+ * SimpleServiceRegistry registry = new SimpleServiceRegistry(reactiveProperties);
+ * }
+ *
+ * @param properties the {@link SimpleReactiveDiscoveryProperties} to use
+ */
public SimpleServiceRegistry(SimpleReactiveDiscoveryProperties properties) {
this(getInstancesMap(properties));
}
+ /**
+ * Constructs a new {@link SimpleServiceRegistry} with the given instances map.
+ *
+ * {@code
+ * Map
+ *
+ * @param instancesMap the map of service IDs to {@link DefaultServiceInstance} lists
+ */
public SimpleServiceRegistry(Map{@code
+ * SimpleServiceRegistry registry = new SimpleServiceRegistry(properties);
+ * DefaultRegistration registration = new DefaultRegistration();
+ * registration.setServiceId("test-service");
+ * registry.register(registration);
+ * }
+ *
+ * @param registration the {@link DefaultRegistration} to register
+ */
@Override
public void register(DefaultRegistration registration) {
List{@code
+ * SimpleServiceRegistry registry = new SimpleServiceRegistry(properties);
+ * registry.register(registration);
+ * registry.deregister(registration);
+ * }
+ *
+ * @param registration the {@link DefaultRegistration} to deregister
+ */
@Override
public void deregister(DefaultRegistration registration) {
List{@code
+ * SimpleServiceRegistry registry = new SimpleServiceRegistry(properties);
+ * registry.close();
+ * }
+ */
@Override
public void close() {
}
+ /**
+ * Sets the status of the given {@link DefaultRegistration} by storing it in the
+ * registration's metadata under the {@link #STATUS_KEY} key.
+ *
+ * {@code
+ * SimpleServiceRegistry registry = new SimpleServiceRegistry(properties);
+ * registry.register(registration);
+ * registry.setStatus(registration, "UP");
+ * }
+ *
+ * @param registration the {@link DefaultRegistration} whose status is to be set
+ * @param status the status value to set
+ */
@Override
public void setStatus(DefaultRegistration registration, String status) {
setMetadata(registration, STATUS_KEY, status);
}
+ /**
+ * Retrieves the status of the given {@link DefaultRegistration} from its metadata.
+ *
+ * {@code
+ * SimpleServiceRegistry registry = new SimpleServiceRegistry(properties);
+ * registry.register(registration);
+ * registry.setStatus(registration, "UP");
+ * String status = registry.getStatus(registration); // "UP"
+ * }
+ *
+ * @param registration the {@link DefaultRegistration} whose status is to be retrieved
+ * @return the status value, or {@code null} if not set
+ */
@Override
public String getStatus(DefaultRegistration registration) {
return getMetadata(registration, STATUS_KEY);
}
+ /**
+ * Returns the list of {@link DefaultServiceInstance} instances for the given
+ * {@link DefaultRegistration}'s service ID.
+ *
+ * {@code
+ * SimpleServiceRegistry registry = new SimpleServiceRegistry(properties);
+ * registry.register(registration);
+ * List
+ *
+ * @param registration the {@link DefaultRegistration} to look up instances for
+ * @return the list of instances for the registration's service ID
+ */
List{@code
+ * SimpleServiceRegistry registry = new SimpleServiceRegistry(properties);
+ * List
+ *
+ * @param serviceId the service ID to look up
+ * @return the list of instances for the service ID
+ */
List{@code ...} blocks to all non-private methods that were
missing documentation across 10 service registry related files.
Methods documented include @Bean factory methods, AOP advices,
lifecycle callbacks, actuator endpoint operations, and protected
template methods.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
...RegistrationEndpointAutoConfiguration.java | 26 ++++++++
.../EventPublishingRegistrationAspect.java | 65 +++++++++++++++++++
.../ServiceRegistryAutoConfiguration.java | 46 +++++++++++++
...oServiceRegistrationAutoConfiguration.java | 29 +++++++++
...bFluxServiceRegistryAutoConfiguration.java | 26 ++++++++
...ebMvcServiceRegistryAutoConfiguration.java | 26 ++++++++
.../WebServiceRegistryAutoConfiguration.java | 13 ++++
.../AbstractServiceRegistrationEndpoint.java | 58 +++++++++++++++++
.../ServiceDeregistrationEndpoint.java | 13 ++++
.../endpoint/ServiceRegistrationEndpoint.java | 28 ++++++++
10 files changed, 330 insertions(+)
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/actuate/autoconfigure/ServiceRegistrationEndpointAutoConfiguration.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/actuate/autoconfigure/ServiceRegistrationEndpointAutoConfiguration.java
index 3b336488..531fc200 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/actuate/autoconfigure/ServiceRegistrationEndpointAutoConfiguration.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/actuate/autoconfigure/ServiceRegistrationEndpointAutoConfiguration.java
@@ -49,6 +49,19 @@
})
public class ServiceRegistrationEndpointAutoConfiguration {
+ /**
+ * Creates a {@link ServiceRegistrationEndpoint} bean for managing service registration via actuator.
+ *
+ * {@code
+ * // The endpoint is auto-configured and accessible at /actuator/serviceRegistration
+ * @Autowired
+ * ServiceRegistrationEndpoint endpoint;
+ * Map
+ *
+ * @return a new {@link ServiceRegistrationEndpoint} instance
+ */
@Bean
@ConditionalOnMissingBean
@ConditionalOnAvailableEndpoint
@@ -56,6 +69,19 @@ public ServiceRegistrationEndpoint serviceRegistrationEndpoint() {
return new ServiceRegistrationEndpoint();
}
+ /**
+ * Creates a {@link ServiceDeregistrationEndpoint} bean for managing service deregistration via actuator.
+ *
+ * {@code
+ * // The endpoint is auto-configured and accessible at /actuator/serviceDeregistration
+ * @Autowired
+ * ServiceDeregistrationEndpoint endpoint;
+ * boolean wasRunning = endpoint.stop();
+ * }
+ *
+ * @return a new {@link ServiceDeregistrationEndpoint} instance
+ */
@Bean
@ConditionalOnMissingBean
@ConditionalOnAvailableEndpoint
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/aspect/EventPublishingRegistrationAspect.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/aspect/EventPublishingRegistrationAspect.java
index de785f4b..0c99526a 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/aspect/EventPublishingRegistrationAspect.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/aspect/EventPublishingRegistrationAspect.java
@@ -59,6 +59,20 @@ public class EventPublishingRegistrationAspect implements ApplicationContextAwar
private ObjectProvider{@code
+ * // This advice is triggered automatically when ServiceRegistry.register() is called:
+ * serviceRegistry.register(registration);
+ * // A RegistrationPreRegisteredEvent is published before actual registration
+ * }
+ *
+ * @param registry the target {@link ServiceRegistry}
+ * @param registration the {@link Registration} being registered
+ */
@Before(value = REGISTER_POINTCUT_EXPRESSION, argNames = "registry, registration")
public void beforeRegister(ServiceRegistry registry, Registration registration) {
if (isIgnored(registry)) {
@@ -70,6 +84,20 @@ public void beforeRegister(ServiceRegistry registry, Registration registration)
});
}
+ /**
+ * AOP advice executed before {@link ServiceRegistry#deregister(Registration)}, publishing a
+ * {@link RegistrationPreDeregisteredEvent}.
+ *
+ * {@code
+ * // This advice is triggered automatically when ServiceRegistry.deregister() is called:
+ * serviceRegistry.deregister(registration);
+ * // A RegistrationPreDeregisteredEvent is published before actual deregistration
+ * }
+ *
+ * @param registry the target {@link ServiceRegistry}
+ * @param registration the {@link Registration} being deregistered
+ */
@Before(value = DEREGISTER_POINTCUT_EXPRESSION, argNames = "registry, registration")
public void beforeDeregister(ServiceRegistry registry, Registration registration) {
if (isIgnored(registry)) {
@@ -78,6 +106,20 @@ public void beforeDeregister(ServiceRegistry registry, Registration registration
context.publishEvent(new RegistrationPreDeregisteredEvent(registry, registration));
}
+ /**
+ * AOP advice executed after {@link ServiceRegistry#register(Registration)}, publishing a
+ * {@link RegistrationRegisteredEvent}.
+ *
+ * {@code
+ * // This advice is triggered automatically after ServiceRegistry.register() completes:
+ * serviceRegistry.register(registration);
+ * // A RegistrationRegisteredEvent is published after successful registration
+ * }
+ *
+ * @param registry the target {@link ServiceRegistry}
+ * @param registration the {@link Registration} that was registered
+ */
@After(value = REGISTER_POINTCUT_EXPRESSION, argNames = "registry, registration")
public void afterRegister(ServiceRegistry registry, Registration registration) {
if (isIgnored(registry)) {
@@ -86,6 +128,20 @@ public void afterRegister(ServiceRegistry registry, Registration registration) {
context.publishEvent(new RegistrationRegisteredEvent(registry, registration));
}
+ /**
+ * AOP advice executed after {@link ServiceRegistry#deregister(Registration)}, publishing a
+ * {@link RegistrationDeregisteredEvent}.
+ *
+ * {@code
+ * // This advice is triggered automatically after ServiceRegistry.deregister() completes:
+ * serviceRegistry.deregister(registration);
+ * // A RegistrationDeregisteredEvent is published after successful deregistration
+ * }
+ *
+ * @param registry the target {@link ServiceRegistry}
+ * @param registration the {@link Registration} that was deregistered
+ */
@After(value = DEREGISTER_POINTCUT_EXPRESSION, argNames = "registry, registration")
public void afterDeregister(ServiceRegistry registry, Registration registration) {
if (isIgnored(registry)) {
@@ -98,6 +154,15 @@ boolean isIgnored(ServiceRegistry registry) {
return MultipleServiceRegistry.class.isAssignableFrom(registry.getClass());
}
+ /**
+ * {@inheritDoc}
+ *
+ * {@code
+ * EventPublishingRegistrationAspect aspect = new EventPublishingRegistrationAspect();
+ * aspect.setApplicationContext(applicationContext);
+ * }
+ */
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/ServiceRegistryAutoConfiguration.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/ServiceRegistryAutoConfiguration.java
index ba838d6d..9eb53ecc 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/ServiceRegistryAutoConfiguration.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/ServiceRegistryAutoConfiguration.java
@@ -55,6 +55,20 @@ public class ServiceRegistryAutoConfiguration {
@ConditionalOnMultipleRegistrationEnabled
static class MultipleConfiguration {
+ /**
+ * Creates a primary {@link MultipleRegistration} bean that aggregates all available
+ * {@link Registration} instances.
+ *
+ * {@code
+ * @Autowired
+ * MultipleRegistration multipleRegistration;
+ * // Access individual registrations from the composite
+ * }
+ *
+ * @param registrations the collection of {@link Registration} instances
+ * @return a new {@link MultipleRegistration} aggregating the provided registrations
+ */
@Primary
@Bean
@ConditionalOnMissingBean
@@ -62,6 +76,21 @@ public MultipleRegistration multipleRegistration(Collection{@code
+ * @Autowired
+ * MultipleServiceRegistry multipleServiceRegistry;
+ * // Register with all service registries at once
+ * multipleServiceRegistry.register(registration);
+ * }
+ *
+ * @param registriesMap a map of bean names to {@link ServiceRegistry} instances
+ * @return a new {@link MultipleServiceRegistry} delegating to all registries
+ */
@Bean
@Primary
@ConditionalOnMissingBean
@@ -69,6 +98,23 @@ public MultipleServiceRegistry multipleServiceRegistry(Map{@code
+ * @Autowired
+ * MultipleAutoServiceRegistration autoRegistration;
+ * // Auto-registration is managed by the Spring lifecycle
+ * boolean running = autoRegistration.isRunning();
+ * }
+ *
+ * @param multipleRegistration the composite {@link MultipleRegistration}
+ * @param multipleServiceRegistry the composite {@link MultipleServiceRegistry}
+ * @param properties the {@link AutoServiceRegistrationProperties}
+ * @return a new {@link MultipleAutoServiceRegistration} instance
+ */
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
@Primary
@Bean
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/SimpleAutoServiceRegistrationAutoConfiguration.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/SimpleAutoServiceRegistrationAutoConfiguration.java
index 7453eef1..c3028236 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/SimpleAutoServiceRegistrationAutoConfiguration.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/SimpleAutoServiceRegistrationAutoConfiguration.java
@@ -80,6 +80,22 @@ public class SimpleAutoServiceRegistrationAutoConfiguration {
)
public static final String ENABLED_PROPERTY_NAME = PROPERTY_NAME_PREFIX + PropertyConstants.ENABLED_PROPERTY_NAME;
+ /**
+ * Creates a {@link Registration} bean from the application name, server properties, and network info.
+ *
+ * {@code
+ * // Auto-configured via Spring Boot; the bean is available for injection:
+ * @Autowired
+ * Registration registration;
+ * String serviceId = registration.getServiceId();
+ * }
+ *
+ * @param applicationName the Spring application name resolved from {@code spring.application.name}
+ * @param serverProperties the {@link ServerProperties} providing the server port
+ * @param inetUtils the {@link InetUtils} for resolving the host address
+ * @return a new {@link DefaultRegistration} instance
+ */
@Bean
public Registration registration(
@Value("${spring.application.name:default}") String applicationName,
@@ -98,6 +114,19 @@ public Registration registration(
return registration;
}
+ /**
+ * Creates an {@link InMemoryServiceRegistry} bean as the default {@link ServiceRegistry} implementation.
+ *
+ * {@code
+ * // Auto-configured when no other ServiceRegistry bean is present:
+ * @Autowired
+ * ServiceRegistry
+ *
+ * @return a new {@link InMemoryServiceRegistry} instance
+ */
@Bean
@ConditionalOnMissingBean
public ServiceRegistry{@code
+ * WebFluxServiceRegistryAutoConfiguration config = new WebFluxServiceRegistryAutoConfiguration();
+ * String contextPath = config.getContextPath(); // returns ""
+ * }
+ *
+ * @return an empty string
+ */
@Override
protected String getContextPath() {
return "";
}
+ /**
+ * {@inheritDoc}
+ * {@code
+ * WebFluxServiceRegistryAutoConfiguration config = new WebFluxServiceRegistryAutoConfiguration();
+ * boolean excluded = config.isExcludedMapping(mapping, patterns); // always false
+ * }
+ *
+ * @param mapping the {@link WebEndpointMapping} to evaluate
+ * @param patterns the URL patterns associated with the mapping
+ * @return always {@code false}
+ */
@Override
protected boolean isExcludedMapping(WebEndpointMapping mapping, String[] patterns) {
return false;
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/WebMvcServiceRegistryAutoConfiguration.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/WebMvcServiceRegistryAutoConfiguration.java
index 1a8fc0d7..b160d563 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/WebMvcServiceRegistryAutoConfiguration.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/WebMvcServiceRegistryAutoConfiguration.java
@@ -55,11 +55,37 @@ public class WebMvcServiceRegistryAutoConfiguration extends WebServiceRegistryAu
@Autowired
private ObjectProvider{@code
+ * // With application property: server.servlet.context-path=/api
+ * String contextPath = config.getContextPath(); // returns "/api"
+ * }
+ *
+ * @return the servlet context path
+ */
@Override
protected String getContextPath() {
return this.contextPath;
}
+ /**
+ * {@inheritDoc}
+ * {@code
+ * boolean excluded = config.isExcludedMapping(mapping, new String[]{"/*"});
+ * // returns true if the mapping matches a built-in filter or DispatcherServlet
+ * }
+ *
+ * @param mapping the {@link WebEndpointMapping} to evaluate
+ * @param patterns the URL patterns associated with the mapping
+ * @return {@code true} if the mapping is a built-in filter or DispatcherServlet mapping
+ */
@Override
protected boolean isExcludedMapping(WebEndpointMapping mapping, String[] patterns) {
return isBuiltInFilterMapping(patterns) || isDispatcherServletMapping(mapping, patterns);
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/WebServiceRegistryAutoConfiguration.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/WebServiceRegistryAutoConfiguration.java
index e025a791..02f61c23 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/WebServiceRegistryAutoConfiguration.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/autoconfigure/WebServiceRegistryAutoConfiguration.java
@@ -62,6 +62,19 @@ public abstract class WebServiceRegistryAutoConfiguration implements Application
@Value("${management.endpoints.web.base-path:/actuator}")
protected String actuatorBasePath;
+ /**
+ * Handles {@link WebEndpointMappingsReadyEvent} by attaching web endpoint mapping metadata
+ * to all available {@link Registration} instances.
+ *
+ * {@code
+ * // This listener is invoked automatically by the Spring event system:
+ * // When WebEndpointMappingsReadyEvent is published, metadata is attached
+ * // to each Registration bean in the ApplicationContext.
+ * }
+ *
+ * @param event the {@link WebEndpointMappingsReadyEvent} containing the web endpoint mappings
+ */
@Override
public final void onApplicationEvent(WebEndpointMappingsReadyEvent event) {
ApplicationContext context = event.getApplicationContext();
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/endpoint/AbstractServiceRegistrationEndpoint.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/endpoint/AbstractServiceRegistrationEndpoint.java
index 5c25b8bb..c9737de9 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/endpoint/AbstractServiceRegistrationEndpoint.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/endpoint/AbstractServiceRegistrationEndpoint.java
@@ -46,6 +46,17 @@ public abstract class AbstractServiceRegistrationEndpoint implements SmartInitia
protected static boolean running;
+ /**
+ * {@inheritDoc}
+ * {@code
+ * // Called automatically by the Spring container after all singletons are instantiated.
+ * // Ensures registration, serviceRegistry, and serviceRegistration fields are populated.
+ * }
+ */
@Override
public void afterSingletonsInstantiated() {
this.registration = registrationProvider.getIfAvailable();
@@ -53,6 +64,19 @@ public void afterSingletonsInstantiated() {
this.serviceRegistration = autoServiceRegistrationProvider.getIfAvailable();
}
+ /**
+ * {@inheritDoc}
+ * {@code
+ * // Called automatically when the embedded web server has been initialized.
+ * // After this event, the port and running state are available.
+ * }
+ *
+ * @param event the {@link WebServerInitializedEvent} carrying the initialized web server
+ */
@Override
public void onApplicationEvent(WebServerInitializedEvent event) {
WebServer webServer = event.getWebServer();
@@ -60,14 +84,48 @@ public void onApplicationEvent(WebServerInitializedEvent event) {
this.running = detectRunning(serviceRegistration);
}
+ /**
+ * Detects whether the given {@link AbstractAutoServiceRegistration} is currently running.
+ *
+ * {@code
+ * boolean running = AbstractServiceRegistrationEndpoint.detectRunning(serviceRegistration);
+ * }
+ *
+ * @param serviceRegistration the {@link AbstractAutoServiceRegistration} to check, may be {@code null}
+ * @return {@code true} if the service registration is running, {@code false} otherwise
+ */
static boolean detectRunning(AbstractAutoServiceRegistration serviceRegistration) {
return serviceRegistration == null ? false : serviceRegistration.isRunning();
}
+ /**
+ * Returns whether the service registration is currently running.
+ *
+ * {@code
+ * if (endpoint.isRunning()) {
+ * // service is registered and running
+ * }
+ * }
+ *
+ * @return {@code true} if the service registration is running, {@code false} otherwise
+ */
protected boolean isRunning() {
return running;
}
+ /**
+ * Sets the running state of the service registration.
+ *
+ * {@code
+ * endpoint.setRunning(true); // mark service as running
+ * endpoint.setRunning(false); // mark service as stopped
+ * }
+ *
+ * @param running {@code true} to mark the service as running, {@code false} otherwise
+ */
public void setRunning(boolean running) {
this.running = running;
}
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/endpoint/ServiceDeregistrationEndpoint.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/endpoint/ServiceDeregistrationEndpoint.java
index a3a5e418..e9858f1d 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/endpoint/ServiceDeregistrationEndpoint.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/endpoint/ServiceDeregistrationEndpoint.java
@@ -15,6 +15,19 @@
@Endpoint(id = "serviceDeregistration")
public class ServiceDeregistrationEndpoint extends AbstractServiceRegistrationEndpoint {
+ /**
+ * Deregisters the service from the {@link ServiceRegistry} if it is currently running.
+ * This is a write operation exposed via the {@code /actuator/serviceDeregistration} endpoint.
+ *
+ * {@code
+ * // Via actuator HTTP POST to /actuator/serviceDeregistration
+ * ServiceDeregistrationEndpoint endpoint = context.getBean(ServiceDeregistrationEndpoint.class);
+ * boolean wasRunning = endpoint.stop();
+ * }
+ *
+ * @return {@code true} if the service was running before deregistration, {@code false} otherwise
+ */
@WriteOperation
public boolean stop() {
boolean isRunning = isRunning();
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/endpoint/ServiceRegistrationEndpoint.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/endpoint/ServiceRegistrationEndpoint.java
index 2fafbff8..afc898ad 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/endpoint/ServiceRegistrationEndpoint.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/endpoint/ServiceRegistrationEndpoint.java
@@ -22,6 +22,21 @@
@Endpoint(id = "serviceRegistration")
public class ServiceRegistrationEndpoint extends AbstractServiceRegistrationEndpoint {
+ /**
+ * Returns metadata about the current service registration, including application name,
+ * registration details, port, status, and running state.
+ * This is a read operation exposed via the {@code /actuator/serviceRegistration} endpoint.
+ *
+ * {@code
+ * // Via actuator HTTP GET to /actuator/serviceRegistration
+ * ServiceRegistrationEndpoint endpoint = context.getBean(ServiceRegistrationEndpoint.class);
+ * Map
+ *
+ * @return a {@link Map} containing service registration metadata
+ */
@ReadOperation
public Map{@code
+ * // Via actuator HTTP POST to /actuator/serviceRegistration
+ * ServiceRegistrationEndpoint endpoint = context.getBean(ServiceRegistrationEndpoint.class);
+ * boolean wasAlreadyRunning = endpoint.start();
+ * }
+ *
+ * @return {@code true} if the service was already running, {@code false} if it was newly registered
+ */
@WriteOperation
public boolean start() {
boolean isRunning = isRunning();
From e733ebc13f05f326f3ab72d8325f54f82208ff3b Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 21 Mar 2026 14:04:51 +0000
Subject: [PATCH 5/7] Add JavaDoc with Example Usage sections to non-private
methods missing documentation
Add JavaDoc comments to constructors, getters, setters, and other
non-private methods across 7 files in the registry event and fault
tolerance packages. Each JavaDoc follows the project style with brief
descriptions, {@link} cross-references, Example Usage sections using
{@code} blocks, and @param/@return tags where applicable.
Files updated:
- RegistrationDeregisteredEvent.java
- RegistrationPreDeregisteredEvent.java
- RegistrationPreRegisteredEvent.java
- RegistrationRegisteredEvent.java
- WeightedRoundRobin.java
- TomcatFaultToleranceAutoConfiguration.java
- TomcatDynamicConfigurationListener.java
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
.../event/RegistrationDeregisteredEvent.java | 27 +++++
.../RegistrationPreDeregisteredEvent.java | 27 +++++
.../event/RegistrationPreRegisteredEvent.java | 27 +++++
.../event/RegistrationRegisteredEvent.java | 27 +++++
.../loadbalancer/WeightedRoundRobin.java | 109 ++++++++++++++++++
...TomcatFaultToleranceAutoConfiguration.java | 12 ++
.../TomcatDynamicConfigurationListener.java | 73 ++++++++++++
7 files changed, 302 insertions(+)
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationDeregisteredEvent.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationDeregisteredEvent.java
index de176582..45ef54ce 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationDeregisteredEvent.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationDeregisteredEvent.java
@@ -30,10 +30,37 @@
*/
public class RegistrationDeregisteredEvent extends RegistrationEvent {
+ /**
+ * Create a new {@link RegistrationDeregisteredEvent} indicating that a
+ * {@link Registration} has been deregistered from the {@link ServiceRegistry}.
+ *
+ * {@code
+ * ServiceRegistry
+ *
+ * @param registry the {@link ServiceRegistry} that performed the deregistration
+ * @param source the {@link Registration} that was deregistered
+ */
public RegistrationDeregisteredEvent(ServiceRegistry{@code
+ * RegistrationDeregisteredEvent event = ...;
+ * RegistrationEvent.Type type = event.getType();
+ * // type == RegistrationEvent.Type.DEREGISTERED
+ * }
+ *
+ * @return {@link Type#DEREGISTERED}
+ */
@Override
public Type getType() {
return DEREGISTERED;
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationPreDeregisteredEvent.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationPreDeregisteredEvent.java
index 3ef61b67..b98fc529 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationPreDeregisteredEvent.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationPreDeregisteredEvent.java
@@ -30,10 +30,37 @@
*/
public class RegistrationPreDeregisteredEvent extends RegistrationEvent {
+ /**
+ * Create a new {@link RegistrationPreDeregisteredEvent} indicating that a
+ * {@link Registration} is about to be deregistered from the {@link ServiceRegistry}.
+ *
+ * {@code
+ * ServiceRegistry
+ *
+ * @param registry the {@link ServiceRegistry} that will perform the deregistration
+ * @param source the {@link Registration} to be deregistered
+ */
public RegistrationPreDeregisteredEvent(ServiceRegistry{@code
+ * RegistrationPreDeregisteredEvent event = ...;
+ * RegistrationEvent.Type type = event.getType();
+ * // type == RegistrationEvent.Type.PRE_DEREGISTERED
+ * }
+ *
+ * @return {@link Type#PRE_DEREGISTERED}
+ */
@Override
public Type getType() {
return PRE_DEREGISTERED;
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationPreRegisteredEvent.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationPreRegisteredEvent.java
index 64073258..8ae5c353 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationPreRegisteredEvent.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationPreRegisteredEvent.java
@@ -30,10 +30,37 @@
*/
public class RegistrationPreRegisteredEvent extends RegistrationEvent {
+ /**
+ * Create a new {@link RegistrationPreRegisteredEvent} indicating that a
+ * {@link Registration} is about to be registered with the {@link ServiceRegistry}.
+ *
+ * {@code
+ * ServiceRegistry
+ *
+ * @param registry the {@link ServiceRegistry} that will perform the registration
+ * @param source the {@link Registration} to be registered
+ */
public RegistrationPreRegisteredEvent(ServiceRegistry{@code
+ * RegistrationPreRegisteredEvent event = ...;
+ * RegistrationEvent.Type type = event.getType();
+ * // type == RegistrationEvent.Type.PRE_REGISTERED
+ * }
+ *
+ * @return {@link Type#PRE_REGISTERED}
+ */
@Override
public Type getType() {
return PRE_REGISTERED;
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationRegisteredEvent.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationRegisteredEvent.java
index 06306ac8..42932dc7 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationRegisteredEvent.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/event/RegistrationRegisteredEvent.java
@@ -30,10 +30,37 @@
*/
public class RegistrationRegisteredEvent extends RegistrationEvent {
+ /**
+ * Create a new {@link RegistrationRegisteredEvent} indicating that a
+ * {@link Registration} has been registered with the {@link ServiceRegistry}.
+ *
+ * {@code
+ * ServiceRegistry
+ *
+ * @param registry the {@link ServiceRegistry} that performed the registration
+ * @param source the {@link Registration} that was registered
+ */
public RegistrationRegisteredEvent(ServiceRegistry{@code
+ * RegistrationRegisteredEvent event = ...;
+ * RegistrationEvent.Type type = event.getType();
+ * // type == RegistrationEvent.Type.REGISTERED
+ * }
+ *
+ * @return {@link Type#REGISTERED}
+ */
@Override
public Type getType() {
return REGISTERED;
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/fault/tolerance/loadbalancer/WeightedRoundRobin.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/fault/tolerance/loadbalancer/WeightedRoundRobin.java
index dc2f30d8..b2991743 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/fault/tolerance/loadbalancer/WeightedRoundRobin.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/fault/tolerance/loadbalancer/WeightedRoundRobin.java
@@ -19,40 +19,149 @@ public class WeightedRoundRobin {
private volatile long lastUpdate;
+ /**
+ * Create a new {@link WeightedRoundRobin} instance with the given identifier.
+ *
+ * {@code
+ * WeightedRoundRobin wrr = new WeightedRoundRobin("server-1");
+ * wrr.setWeight(5);
+ * }
+ *
+ * @param id the unique identifier for this weighted round-robin entry
+ */
public WeightedRoundRobin(String id) {
this.id = id;
}
+ /**
+ * Get the unique identifier for this {@link WeightedRoundRobin} entry.
+ *
+ * {@code
+ * WeightedRoundRobin wrr = new WeightedRoundRobin("server-1");
+ * String id = wrr.getId(); // "server-1"
+ * }
+ *
+ * @return the identifier
+ */
public String getId() {
return id;
}
+ /**
+ * Get the current weight of this {@link WeightedRoundRobin} entry.
+ *
+ * {@code
+ * WeightedRoundRobin wrr = new WeightedRoundRobin("server-1");
+ * wrr.setWeight(5);
+ * int weight = wrr.getWeight(); // 5
+ * }
+ *
+ * @return the current weight
+ */
public int getWeight() {
return weight;
}
+ /**
+ * Set the weight for this {@link WeightedRoundRobin} entry and reset the current counter.
+ *
+ * {@code
+ * WeightedRoundRobin wrr = new WeightedRoundRobin("server-1");
+ * wrr.setWeight(10);
+ * }
+ *
+ * @param weight the new weight value
+ */
public void setWeight(int weight) {
this.weight = weight;
current.reset();
}
+ /**
+ * Increase the current counter by the weight value and return the updated value.
+ * Used during weighted round-robin selection to accumulate the weight for this entry.
+ *
+ * {@code
+ * WeightedRoundRobin wrr = new WeightedRoundRobin("server-1");
+ * wrr.setWeight(5);
+ * long current = wrr.increaseCurrent(); // 5
+ * current = wrr.increaseCurrent(); // 10
+ * }
+ *
+ * @return the updated current counter value
+ */
public long increaseCurrent() {
current.add(weight);
return current.longValue();
}
+ /**
+ * Subtract the total weight from the current counter after this entry has been selected.
+ * This is part of the weighted round-robin algorithm to reduce the selected entry's counter.
+ *
+ * {@code
+ * WeightedRoundRobin wrr = new WeightedRoundRobin("server-1");
+ * wrr.setWeight(5);
+ * wrr.increaseCurrent();
+ * wrr.sel(10); // subtract total weight of all entries
+ * }
+ *
+ * @param total the total weight of all entries to subtract
+ */
public void sel(int total) {
current.add(-1 * total);
}
+ /**
+ * Get the timestamp of the last update to this {@link WeightedRoundRobin} entry.
+ *
+ * {@code
+ * WeightedRoundRobin wrr = new WeightedRoundRobin("server-1");
+ * wrr.setLastUpdate(System.currentTimeMillis());
+ * long lastUpdate = wrr.getLastUpdate();
+ * }
+ *
+ * @return the last update timestamp in milliseconds
+ */
public long getLastUpdate() {
return lastUpdate;
}
+ /**
+ * Set the timestamp of the last update to this {@link WeightedRoundRobin} entry.
+ *
+ * {@code
+ * WeightedRoundRobin wrr = new WeightedRoundRobin("server-1");
+ * wrr.setLastUpdate(System.currentTimeMillis());
+ * }
+ *
+ * @param lastUpdate the last update timestamp in milliseconds
+ */
public void setLastUpdate(long lastUpdate) {
this.lastUpdate = lastUpdate;
}
+ /**
+ * Returns a string representation of this {@link WeightedRoundRobin} including
+ * its id, weight, current counter, and last update timestamp.
+ *
+ * {@code
+ * WeightedRoundRobin wrr = new WeightedRoundRobin("server-1");
+ * wrr.setWeight(5);
+ * String s = wrr.toString(); // "WeightedRoundRobin[id='server-1', weight=5, current=0, lastUpdate=0]"
+ * }
+ *
+ * @return a string representation of this entry
+ */
@Override
public String toString() {
return new StringJoiner(", ", WeightedRoundRobin.class.getSimpleName() + "[", "]")
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/fault/tolerance/tomcat/autoconfigure/TomcatFaultToleranceAutoConfiguration.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/fault/tolerance/tomcat/autoconfigure/TomcatFaultToleranceAutoConfiguration.java
index 58b1cd92..b32ad811 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/fault/tolerance/tomcat/autoconfigure/TomcatFaultToleranceAutoConfiguration.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/fault/tolerance/tomcat/autoconfigure/TomcatFaultToleranceAutoConfiguration.java
@@ -72,6 +72,18 @@ public class TomcatFaultToleranceAutoConfiguration {
)
public static final String ENABLED_PROPERTY_NAME = TOMCAT_PROPERTY_PREFIX + "." + PropertyConstants.ENABLED_PROPERTY_NAME;
+ /**
+ * Handles the {@link WebServerInitializedEvent} to register a {@link TomcatDynamicConfigurationListener}
+ * when the embedded web server is a {@link TomcatWebServer}.
+ *
+ * {@code
+ * // Automatically invoked by Spring when WebServerInitializedEvent is published.
+ * // The listener is registered as an ApplicationListener on the web application context.
+ * }
+ *
+ * @param event the {@link WebServerInitializedEvent} triggered after the web server starts
+ */
@EventListener(WebServerInitializedEvent.class)
public void onWebServerInitializedEvent(WebServerInitializedEvent event) {
WebServerApplicationContext webServerApplicationContext = event.getApplicationContext();
diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/fault/tolerance/tomcat/event/TomcatDynamicConfigurationListener.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/fault/tolerance/tomcat/event/TomcatDynamicConfigurationListener.java
index 10daa3c4..42abdb41 100644
--- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/fault/tolerance/tomcat/event/TomcatDynamicConfigurationListener.java
+++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/fault/tolerance/tomcat/event/TomcatDynamicConfigurationListener.java
@@ -68,6 +68,25 @@ public class TomcatDynamicConfigurationListener implements ApplicationListener{@code
+ * TomcatWebServer tomcatWebServer = ...;
+ * ServerProperties serverProperties = ...;
+ * ConfigurableApplicationContext context = ...;
+ * TomcatDynamicConfigurationListener listener =
+ * new TomcatDynamicConfigurationListener(tomcatWebServer, serverProperties, context);
+ * context.addApplicationListener(listener);
+ * }
+ *
+ * @param tomcatWebServer the {@link TomcatWebServer} to reconfigure dynamically
+ * @param serverProperties the current {@link ServerProperties}
+ * @param context the {@link ConfigurableApplicationContext} for environment access
+ */
public TomcatDynamicConfigurationListener(TomcatWebServer tomcatWebServer, ServerProperties serverProperties,
ConfigurableApplicationContext context) {
this.tomcatWebServer = tomcatWebServer;
@@ -85,6 +104,18 @@ private void initCurrentServerProperties() {
this.currentServerProperties = getCurrentServerProperties(environment);
}
+ /**
+ * Handles an {@link EnvironmentChangeEvent} by reconfiguring the Tomcat connector
+ * if any server-related properties have changed.
+ *
+ * {@code
+ * // Automatically invoked by Spring when an EnvironmentChangeEvent is published.
+ * // Reconfigures Tomcat settings such as thread pool size, connection timeout, etc.
+ * }
+ *
+ * @param event the {@link EnvironmentChangeEvent} containing the changed property keys
+ */
@Override
public void onApplicationEvent(EnvironmentChangeEvent event) {
if (!isSourceFrom(event)) {
@@ -146,6 +177,20 @@ private void configureConnector(ServerProperties refreshableServerProperties) {
configureHttp11Protocol(refreshableServerProperties, connector, protocolHandler);
}
+ /**
+ * Configure the Tomcat {@link AbstractProtocol} settings such as thread pool sizes,
+ * accept count, connection timeout, and max connections from the refreshed {@link ServerProperties}.
+ *
+ * {@code
+ * ServerProperties refreshedProperties = ...;
+ * ProtocolHandler protocolHandler = connector.getProtocolHandler();
+ * listener.configureProtocol(refreshedProperties, protocolHandler);
+ * }
+ *
+ * @param refreshableServerProperties the refreshed {@link ServerProperties} to apply
+ * @param protocolHandler the {@link ProtocolHandler} to configure
+ */
void configureProtocol(ServerProperties refreshableServerProperties, ProtocolHandler protocolHandler) {
if (protocolHandler instanceof AbstractProtocol) {
@@ -194,6 +239,22 @@ void configureProtocol(ServerProperties refreshableServerProperties, ProtocolHan
}
}
+ /**
+ * Configure the Tomcat {@link AbstractHttp11Protocol} settings such as max HTTP header size,
+ * max swallow size, and max HTTP form POST size from the refreshed {@link ServerProperties}.
+ *
+ * {@code
+ * ServerProperties refreshedProperties = ...;
+ * Connector connector = tomcatWebServer.getTomcat().getConnector();
+ * ProtocolHandler protocolHandler = connector.getProtocolHandler();
+ * listener.configureHttp11Protocol(refreshedProperties, connector, protocolHandler);
+ * }
+ *
+ * @param refreshableServerProperties the refreshed {@link ServerProperties} to apply
+ * @param connector the Tomcat {@link Connector}
+ * @param protocolHandler the {@link ProtocolHandler} to configure
+ */
void configureHttp11Protocol(ServerProperties refreshableServerProperties, Connector connector, ProtocolHandler protocolHandler) {
if (protocolHandler instanceof AbstractHttp11Protocol) {
AbstractHttp11Protocol protocol = (AbstractHttp11Protocol) protocolHandler;
@@ -236,6 +297,18 @@ private int toIntBytes(DataSize dataSize) {
return (int) dataSize.toBytes();
}
+ /**
+ * Check whether the given integer value is positive (greater than zero).
+ *
+ * {@code
+ * boolean result = listener.isPositive(10); // true
+ * boolean result2 = listener.isPositive(0); // false
+ * }
+ *
+ * @param value the value to check
+ * @return {@code true} if the value is greater than zero
+ */
boolean isPositive(int value) {
return value > 0;
}
From 99f5660ceb7ba5cdac33714532800c5094d66c28 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 21 Mar 2026 14:10:51 +0000
Subject: [PATCH 6/7] Add JavaDoc with Example Usage sections to non-private
methods in openfeign module
Add comprehensive JavaDoc comments including brief descriptions, @link
cross-references, Example Usage sections with {@code ...}
blocks, and @param/@return tags to all non-private methods that were
missing documentation across 14 files in the openfeign module.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
...ignClientAutoRefreshAutoConfiguration.java | 51 +++++++
...FeignClientSpecificationPostProcessor.java | 15 ++
.../autorefresh/AutoRefreshCapability.java | 117 +++++++++++++++
...ignClientConfigurationChangedListener.java | 37 +++++
.../autorefresh/FeignComponentRegistry.java | 127 ++++++++++++++++
.../CompositedRequestInterceptor.java | 99 +++++++++++++
.../components/DecoratedContract.java | 37 +++++
.../components/DecoratedDecoder.java | 41 ++++++
.../components/DecoratedEncoder.java | 39 +++++
.../components/DecoratedErrorDecoder.java | 37 +++++
.../components/DecoratedFeignComponent.java | 138 ++++++++++++++++++
.../components/DecoratedQueryMapEncoder.java | 51 +++++++
.../components/DecoratedRetryer.java | 61 ++++++++
.../components/NoOpRequestInterceptor.java | 21 +++
14 files changed, 871 insertions(+)
diff --git a/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autoconfigure/FeignClientAutoRefreshAutoConfiguration.java b/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autoconfigure/FeignClientAutoRefreshAutoConfiguration.java
index 46f2e3d5..7e851e56 100644
--- a/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autoconfigure/FeignClientAutoRefreshAutoConfiguration.java
+++ b/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autoconfigure/FeignClientAutoRefreshAutoConfiguration.java
@@ -23,6 +23,18 @@
@ConditionalOnBean(EnableFeignAutoRefresh.Marker.class)
public class FeignClientAutoRefreshAutoConfiguration {
+ /**
+ * Creates a {@link FeignBuilderCustomizer} that adds the {@link NoOpRequestInterceptor}
+ * as a default request interceptor to every Feign client builder.
+ *
+ * {@code
+ * // Automatically registered as a Spring bean; customizes every Feign builder
+ * FeignBuilderCustomizer customizer = addDefaultRequestInterceptorCustomizer();
+ * }
+ *
+ * @return a {@link FeignBuilderCustomizer} that adds the {@link NoOpRequestInterceptor}
+ */
@Bean
public FeignBuilderCustomizer addDefaultRequestInterceptorCustomizer() {
return builder -> {
@@ -30,6 +42,18 @@ public FeignBuilderCustomizer addDefaultRequestInterceptorCustomizer() {
};
}
+ /**
+ * Handles the {@link ApplicationReadyEvent} to register the
+ * {@link FeignClientConfigurationChangedListener} after the application is fully initialized.
+ *
+ * {@code
+ * // Invoked automatically by the Spring event system on application ready
+ * onApplicationReadyEvent(applicationReadyEvent);
+ * }
+ *
+ * @param event the {@link ApplicationReadyEvent} fired when the application is ready
+ */
@EventListener(ApplicationReadyEvent.class)
public void onApplicationReadyEvent(ApplicationReadyEvent event) {
/**
@@ -38,11 +62,38 @@ public void onApplicationReadyEvent(ApplicationReadyEvent event) {
registerFeignClientConfigurationChangedListener(event);
}
+ /**
+ * Creates the {@link FeignComponentRegistry} bean that tracks decorated Feign components
+ * and supports auto-refresh when configuration properties change.
+ *
+ * {@code
+ * // Automatically registered as a Spring bean
+ * FeignComponentRegistry registry = feignClientRegistry(clientProperties, beanFactory);
+ * }
+ *
+ * @param clientProperties the {@link FeignClientProperties} providing the default config name
+ * @param beanFactory the {@link BeanFactory} used for component instantiation
+ * @return a new {@link FeignComponentRegistry} instance
+ */
@Bean
public FeignComponentRegistry feignClientRegistry(FeignClientProperties clientProperties, BeanFactory beanFactory) {
return new FeignComponentRegistry(clientProperties.getDefaultConfig(), beanFactory);
}
+ /**
+ * Creates the {@link FeignClientSpecificationPostProcessor} bean that injects
+ * the {@link io.microsphere.spring.cloud.openfeign.autorefresh.AutoRefreshCapability}
+ * into default Feign client specifications.
+ *
+ * {@code
+ * // Automatically registered as a Spring bean
+ * FeignClientSpecificationPostProcessor processor = feignClientSpecificationPostProcessor();
+ * }
+ *
+ * @return a new {@link FeignClientSpecificationPostProcessor} instance
+ */
@Bean
public FeignClientSpecificationPostProcessor feignClientSpecificationPostProcessor() {
return new FeignClientSpecificationPostProcessor();
diff --git a/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autoconfigure/FeignClientSpecificationPostProcessor.java b/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autoconfigure/FeignClientSpecificationPostProcessor.java
index 1dd44c8d..895c3bc2 100644
--- a/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autoconfigure/FeignClientSpecificationPostProcessor.java
+++ b/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autoconfigure/FeignClientSpecificationPostProcessor.java
@@ -27,6 +27,21 @@ public class FeignClientSpecificationPostProcessor implements BeanPostProcessor
private static final Class> FEIGN_CLIENT_SPECIFICATION_CLASS = FeignClientSpecification.class;
+ /**
+ * Injects the {@link AutoRefreshCapability} into default {@link FeignClientSpecification}
+ * beans after initialization.
+ *
+ * {@code
+ * // Invoked automatically by the Spring container during bean post-processing
+ * Object processed = postProcessAfterInitialization(bean, "default.my-client");
+ * }
+ *
+ * @param bean the bean instance that has been initialized
+ * @param beanName the name of the bean in the Spring context
+ * @return the (possibly modified) bean instance
+ * @throws BeansException if post-processing fails
+ */
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
Class> beanType = getTargetClass(bean);
diff --git a/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autorefresh/AutoRefreshCapability.java b/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autorefresh/AutoRefreshCapability.java
index ebc5b9f2..d9dc7ddd 100644
--- a/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autorefresh/AutoRefreshCapability.java
+++ b/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autorefresh/AutoRefreshCapability.java
@@ -38,6 +38,19 @@ public class AutoRefreshCapability implements Capability, ApplicationContextAwar
private String contextId;
+ /**
+ * Constructs an {@link AutoRefreshCapability} with the required dependencies.
+ *
+ * {@code
+ * AutoRefreshCapability capability = new AutoRefreshCapability(
+ * clientProperties, contextFactory, componentRegistry);
+ * }
+ *
+ * @param clientProperties the {@link FeignClientProperties} providing Feign client configuration
+ * @param contextFactory the {@link NamedContextFactory} for resolving per-client contexts
+ * @param componentRegistry the {@link FeignComponentRegistry} to register decorated components
+ */
public AutoRefreshCapability(FeignClientProperties clientProperties,
NamedContextFactory{@code
+ * AutoRefreshCapability capability = new AutoRefreshCapability(props, factory, registry);
+ * capability.setApplicationContext(applicationContext);
+ * }
+ *
+ * @param applicationContext the {@link ApplicationContext} for this Feign client
+ * @throws BeansException if the context cannot be set
+ */
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.contextId = applicationContext.getEnvironment().getProperty("spring.cloud.openfeign.client.name");
}
+ /**
+ * Enriches the given {@link Retryer} by wrapping it in a {@link DecoratedRetryer}
+ * that supports auto-refresh on configuration changes.
+ *
+ * {@code
+ * Retryer original = new Retryer.Default();
+ * Retryer enriched = capability.enrich(original);
+ * }
+ *
+ * @param retryer the original {@link Retryer} to enrich, or {@code null}
+ * @return the decorated {@link Retryer}, or {@code null} if the input is {@code null}
+ */
@Override
public Retryer enrich(Retryer retryer) {
if (retryer == null) {
@@ -63,6 +102,19 @@ public Retryer enrich(Retryer retryer) {
return decoratedRetryer;
}
+ /**
+ * Enriches the given {@link Contract} by wrapping it in a {@link DecoratedContract}
+ * that supports auto-refresh on configuration changes.
+ *
+ * {@code
+ * Contract original = new Contract.Default();
+ * Contract enriched = capability.enrich(original);
+ * }
+ *
+ * @param contract the original {@link Contract} to enrich, or {@code null}
+ * @return the decorated {@link Contract}, or {@code null} if the input is {@code null}
+ */
@Override
public Contract enrich(Contract contract) {
if (contract == null) {
@@ -75,6 +127,19 @@ public Contract enrich(Contract contract) {
return decoratedContract;
}
+ /**
+ * Enriches the given {@link Decoder} by wrapping it in a {@link DecoratedDecoder}
+ * that supports auto-refresh on configuration changes.
+ *
+ * {@code
+ * Decoder original = new Decoder.Default();
+ * Decoder enriched = capability.enrich(original);
+ * }
+ *
+ * @param decoder the original {@link Decoder} to enrich, or {@code null}
+ * @return the decorated {@link Decoder}, or {@code null} if the input is {@code null}
+ */
@Override
public Decoder enrich(Decoder decoder) {
if (decoder == null) {
@@ -87,6 +152,19 @@ public Decoder enrich(Decoder decoder) {
return decoratedDecoder;
}
+ /**
+ * Enriches the given {@link Encoder} by wrapping it in a {@link DecoratedEncoder}
+ * that supports auto-refresh on configuration changes.
+ *
+ * {@code
+ * Encoder original = new Encoder.Default();
+ * Encoder enriched = capability.enrich(original);
+ * }
+ *
+ * @param encoder the original {@link Encoder} to enrich, or {@code null}
+ * @return the decorated {@link Encoder}, or {@code null} if the input is {@code null}
+ */
@Override
public Encoder enrich(Encoder encoder) {
if (encoder == null) {
@@ -99,6 +177,19 @@ public Encoder enrich(Encoder encoder) {
return decoratedEncoder;
}
+ /**
+ * Enriches the given {@link ErrorDecoder} by wrapping it in a {@link DecoratedErrorDecoder}
+ * that supports auto-refresh on configuration changes.
+ *
+ * {@code
+ * ErrorDecoder original = new ErrorDecoder.Default();
+ * ErrorDecoder enriched = capability.enrich(original);
+ * }
+ *
+ * @param decoder the original {@link ErrorDecoder} to enrich, or {@code null}
+ * @return the decorated {@link ErrorDecoder}, or {@code null} if the input is {@code null}
+ */
public ErrorDecoder enrich(ErrorDecoder decoder) {
if (decoder == null) {
return null;
@@ -110,6 +201,19 @@ public ErrorDecoder enrich(ErrorDecoder decoder) {
return decoratedErrorDecoder;
}
+ /**
+ * Enriches the given {@link RequestInterceptor} by registering it in the
+ * {@link FeignComponentRegistry} as part of a {@link io.microsphere.spring.cloud.openfeign.components.CompositedRequestInterceptor}.
+ *
+ * {@code
+ * RequestInterceptor original = template -> template.header("X-Custom", "value");
+ * RequestInterceptor enriched = capability.enrich(original);
+ * }
+ *
+ * @param requestInterceptor the original {@link RequestInterceptor} to enrich, or {@code null}
+ * @return the composited {@link RequestInterceptor}, or {@code null} if the input is {@code null}
+ */
@Override
public RequestInterceptor enrich(RequestInterceptor requestInterceptor) {
if (requestInterceptor == null) {
@@ -118,6 +222,19 @@ public RequestInterceptor enrich(RequestInterceptor requestInterceptor) {
return this.componentRegistry.registerRequestInterceptor(contextId, requestInterceptor);
}
+ /**
+ * Enriches the given {@link QueryMapEncoder} by wrapping it in a {@link DecoratedQueryMapEncoder}
+ * that supports auto-refresh on configuration changes.
+ *
+ * {@code
+ * QueryMapEncoder original = new QueryMapEncoder.Default();
+ * QueryMapEncoder enriched = capability.enrich(original);
+ * }
+ *
+ * @param queryMapEncoder the original {@link QueryMapEncoder} to enrich, or {@code null}
+ * @return the decorated {@link QueryMapEncoder}, or {@code null} if the input is {@code null}
+ */
@Override
public QueryMapEncoder enrich(QueryMapEncoder queryMapEncoder) {
if (queryMapEncoder == null) {
diff --git a/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autorefresh/FeignClientConfigurationChangedListener.java b/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autorefresh/FeignClientConfigurationChangedListener.java
index 835245b8..7fae5c63 100644
--- a/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autorefresh/FeignClientConfigurationChangedListener.java
+++ b/microsphere-spring-cloud-openfeign/src/main/java/io/microsphere/spring/cloud/openfeign/autorefresh/FeignClientConfigurationChangedListener.java
@@ -15,12 +15,36 @@ public class FeignClientConfigurationChangedListener implements ApplicationListe
private final FeignComponentRegistry registry;
+ /**
+ * Constructs a listener that refreshes Feign components when the environment changes.
+ *
+ * {@code
+ * FeignComponentRegistry registry = ...;
+ * FeignClientConfigurationChangedListener listener =
+ * new FeignClientConfigurationChangedListener(registry);
+ * }
+ *
+ * @param registry the {@link FeignComponentRegistry} used to refresh affected Feign components
+ */
public FeignClientConfigurationChangedListener(FeignComponentRegistry registry) {
this.registry = registry;
}
private final String PREFIX = "spring.cloud.openfeign.client.config.";
+ /**
+ * Handles an {@link EnvironmentChangeEvent} by resolving which Feign clients are affected
+ * and triggering a refresh on the corresponding components in the registry.
+ *
+ * {@code
+ * // Invoked automatically by the Spring event system
+ * listener.onApplicationEvent(environmentChangeEvent);
+ * }
+ *
+ * @param event the {@link EnvironmentChangeEvent} containing the changed property keys
+ */
@Override
public void onApplicationEvent(EnvironmentChangeEvent event) {
Map{@code
+ * Map
+ *
+ * @param event the {@link EnvironmentChangeEvent} containing the changed property keys
+ * @return a map of client names to their changed configuration sub-keys
+ */
protected Map{@code
+ * Class> componentClass = FeignComponentRegistry.getComponentClass("retryer");
+ * // returns Retryer.class
+ * }
+ *
+ * @param config the configuration property key (e.g. {@code "retryer"}, {@code "decoder"})
+ * @return the mapped Feign component {@link Class}, or {@code null} if not found
+ */
protected static Class> getComponentClass(String config) {
if (isBlank(config)) {
return null;
@@ -68,16 +80,53 @@ protected static Class> getComponentClass(String config) {
return configComponentMappings.get(normalizedConfig);
}
+ /**
+ * Normalizes a configuration key by stripping array index suffixes and converting
+ * to dashed form.
+ *
+ * {@code
+ * String normalized = FeignComponentRegistry.normalizeConfig("requestInterceptors[0]");
+ * // returns "request-interceptors"
+ * }
+ *
+ * @param config the raw configuration property key
+ * @return the normalized, dashed-form configuration key
+ */
static String normalizeConfig(String config) {
String normalizedConfig = substringBefore(config, LEFT_SQUARE_BRACKET);
return toDashedForm(normalizedConfig);
}
+ /**
+ * Constructs a {@link FeignComponentRegistry} with the given default client name
+ * and {@link BeanFactory}.
+ *
+ * {@code
+ * FeignComponentRegistry registry = new FeignComponentRegistry("default", beanFactory);
+ * }
+ *
+ * @param defaultClientName the name of the default Feign client configuration
+ * @param beanFactory the {@link BeanFactory} used for component resolution
+ */
public FeignComponentRegistry(String defaultClientName, BeanFactory beanFactory) {
this.defaultClientName = defaultClientName;
this.beanFactory = beanFactory;
}
+ /**
+ * Registers a list of {@link Refreshable} components for the specified Feign client.
+ *
+ * {@code
+ * List
+ *
+ * @param clientName the Feign client name
+ * @param components the list of {@link Refreshable} components to register
+ */
public void register(String clientName, List{@code
+ * registry.register("my-client", decoratedContract);
+ * }
+ *
+ * @param clientName the Feign client name
+ * @param component the {@link Refreshable} component to register
+ */
public void register(String clientName, Refreshable component) {
register(clientName, ofList(component));
}
+ /**
+ * Registers a {@link RequestInterceptor} for the specified Feign client. Interceptors
+ * are collected into a {@link CompositedRequestInterceptor} per client.
+ *
+ * {@code
+ * RequestInterceptor interceptor = template -> template.header("X-Custom", "value");
+ * RequestInterceptor result = registry.registerRequestInterceptor("my-client", interceptor);
+ * }
+ *
+ * @param clientName the Feign client name
+ * @param requestInterceptor the {@link RequestInterceptor} to register
+ * @return the {@link CompositedRequestInterceptor} if this is the first interceptor
+ * for the client, or {@link io.microsphere.spring.cloud.openfeign.components.NoOpRequestInterceptor#INSTANCE} otherwise
+ */
public RequestInterceptor registerRequestInterceptor(String clientName, RequestInterceptor requestInterceptor) {
assertNotBlank(clientName, () -> "The 'clientName' must not be blank!");
assertNotNull(requestInterceptor, () -> "The 'requestInterceptor' must not be null!");
@@ -101,10 +176,35 @@ public RequestInterceptor registerRequestInterceptor(String clientName, RequestI
}
+ /**
+ * Refreshes the Feign components for the specified client whose configurations have changed.
+ *
+ * {@code
+ * registry.refresh("my-client", "retryer", "decoder");
+ * }
+ *
+ * @param clientName the Feign client name
+ * @param changedConfigs the configuration keys that have changed
+ */
public void refresh(String clientName, String... changedConfigs) {
refresh(clientName, ofSet(changedConfigs));
}
+ /**
+ * Refreshes the Feign components for the specified client based on a set of changed
+ * configuration keys. If the default client configuration changed, all registered
+ * components are refreshed.
+ *
+ * {@code
+ * Set
+ *
+ * @param clientName the Feign client name
+ * @param changedConfigs the set of changed configuration sub-keys
+ */
public synchronized void refresh(String clientName, Set{@code
+ * boolean present = FeignComponentRegistry.isComponentPresent(
+ * refreshableComponent, List.of(Retryer.class, Decoder.class));
+ * }
+ *
+ * @param component the {@link Refreshable} component to check
+ * @param effectiveComponents the component classes to match against
+ * @return {@code true} if the component matches any of the effective classes
+ */
static boolean isComponentPresent(Refreshable component, Iterable{@code
+ * boolean present = FeignComponentRegistry.isComponentClassPresent(
+ * DecoratedRetryer.class, List.of(Retryer.class));
+ * }
+ *
+ * @param componentsClass the class to check
+ * @param effectiveComponents the component classes to match against
+ * @return {@code true} if the class is assignable from any effective class
+ */
static boolean isComponentClassPresent(Class> componentsClass, Iterable{@code
+ * CompositedRequestInterceptor interceptor =
+ * new CompositedRequestInterceptor("my-client", beanFactory);
+ * }
+ *
+ * @param contextId the Feign client context ID
+ * @param beanFactory the {@link BeanFactory} for resolving interceptor instances
+ */
public CompositedRequestInterceptor(String contextId, BeanFactory beanFactory) {
this.beanFactory = beanFactory;
this.contextId = contextId;
}
+ /**
+ * Returns an unmodifiable view of the registered {@link RequestInterceptor} instances.
+ *
+ * {@code
+ * Set
+ *
+ * @return an unmodifiable {@link Set} of registered request interceptors
+ */
public Set{@code
+ * RequestTemplate template = new RequestTemplate();
+ * compositedInterceptor.apply(template);
+ * }
+ *
+ * @param template the {@link RequestTemplate} to apply interceptors to
+ */
@Override
public void apply(RequestTemplate template) {
synchronized (this.set) {
@@ -49,6 +83,19 @@ public void apply(RequestTemplate template) {
}
}
+ /**
+ * Adds a {@link RequestInterceptor} to this composite. Returns {@code true} if this
+ * is the first interceptor added (i.e., the composite was previously empty).
+ *
+ * {@code
+ * boolean wasFirst = compositedInterceptor.addRequestInterceptor(
+ * template -> template.header("Authorization", "Bearer token"));
+ * }
+ *
+ * @param requestInterceptor the {@link RequestInterceptor} to add
+ * @return {@code true} if this was the first interceptor added, {@code false} otherwise
+ */
public boolean addRequestInterceptor(RequestInterceptor requestInterceptor) {
synchronized (this.set) {
boolean isFirst = this.set.isEmpty();
@@ -61,6 +108,16 @@ private RequestInterceptor getInterceptorOrInstantiate(Class extends RequestIn
return getOrInstantiate(clazz);
}
+ /**
+ * Refreshes the set of {@link RequestInterceptor} instances by re-reading the
+ * {@link FeignClientProperties} configuration for request interceptors, default
+ * headers, and default query parameters.
+ *
+ * {@code
+ * compositedInterceptor.refresh();
+ * }
+ */
@Override
public void refresh() {
FeignClientProperties properties = getOrInstantiate(FeignClientProperties.class);
@@ -110,6 +167,20 @@ public void refresh() {
}
}
+ /**
+ * Adds all elements from the source collection (obtained via the supplier) into the
+ * target collection if the source is not empty.
+ *
+ * {@code
+ * Collection
+ *
+ * @param {@code
+ * FeignClientProperties properties = getOrInstantiate(FeignClientProperties.class);
+ * }
+ *
+ * @param {@code
+ * Map
+ *
+ * @param