Skip to content

Commit 4cb9d81

Browse files
committed
Include non-default candidates in metrics and health
Previously, when Actuator expected to find multiple beans of the same type, it used Map<String, Type> to inject them. Unfortunately, this does not include beans that are not default candidates and there's no way to request that autowiring includes such beans with Map-based injection. This commit switches from Map-based injection to querying the bean factory for the desired beans. This is done using SimpleAutowireCandidateResolver's new helper method, resolveAutowireCandidates, that returns a Map<String, Type> of beans including those that are not default candidates but excluding those that are not autowire candidates. Closes gh-43481
1 parent f6f0daa commit 4cb9d81

File tree

31 files changed

+400
-179
lines changed

31 files changed

+400
-179
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/amqp/RabbitHealthContributorAutoConfiguration.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,9 +16,8 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.amqp;
1818

19-
import java.util.Map;
20-
2119
import org.springframework.amqp.rabbit.core.RabbitTemplate;
20+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2221
import org.springframework.boot.actuate.amqp.RabbitHealthIndicator;
2322
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
2423
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
@@ -50,8 +49,8 @@ public RabbitHealthContributorAutoConfiguration() {
5049

5150
@Bean
5251
@ConditionalOnMissingBean(name = { "rabbitHealthIndicator", "rabbitHealthContributor" })
53-
public HealthContributor rabbitHealthContributor(Map<String, RabbitTemplate> rabbitTemplates) {
54-
return createContributor(rabbitTemplates);
52+
public HealthContributor rabbitHealthContributor(ConfigurableListableBeanFactory beanFactory) {
53+
return createContributor(beanFactory, RabbitTemplate.class);
5554
}
5655

5756
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cache/CachesEndpointAutoConfiguration.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,8 +16,8 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.cache;
1818

19-
import java.util.Map;
20-
19+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
20+
import org.springframework.beans.factory.support.SimpleAutowireCandidateResolver;
2121
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
2222
import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure;
2323
import org.springframework.boot.actuate.cache.CachesEndpoint;
@@ -45,8 +45,9 @@ public class CachesEndpointAutoConfiguration {
4545

4646
@Bean
4747
@ConditionalOnMissingBean
48-
public CachesEndpoint cachesEndpoint(Map<String, CacheManager> cacheManagers) {
49-
return new CachesEndpoint(cacheManagers);
48+
public CachesEndpoint cachesEndpoint(ConfigurableListableBeanFactory beanFactory) {
49+
return new CachesEndpoint(
50+
SimpleAutowireCandidateResolver.resolveAutowireCandidates(beanFactory, CacheManager.class));
5051
}
5152

5253
@Bean

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cassandra/CassandraHealthContributorConfigurations.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
2020

2121
import com.datastax.oss.driver.api.core.CqlSession;
2222

23+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2324
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
2425
import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration;
2526
import org.springframework.boot.actuate.cassandra.CassandraDriverHealthIndicator;
@@ -49,8 +50,8 @@ static class CassandraDriverConfiguration
4950

5051
@Bean
5152
@ConditionalOnMissingBean(name = { "cassandraHealthIndicator", "cassandraHealthContributor" })
52-
HealthContributor cassandraHealthContributor(Map<String, CqlSession> sessions) {
53-
return createContributor(sessions);
53+
HealthContributor cassandraHealthContributor(ConfigurableListableBeanFactory beanFactory) {
54+
return createContributor(beanFactory, CqlSession.class);
5455
}
5556

5657
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/couchbase/CouchbaseHealthContributorAutoConfiguration.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,10 +16,9 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.couchbase;
1818

19-
import java.util.Map;
20-
2119
import com.couchbase.client.java.Cluster;
2220

21+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2322
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
2423
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
2524
import org.springframework.boot.actuate.couchbase.CouchbaseHealthIndicator;
@@ -55,8 +54,8 @@ public CouchbaseHealthContributorAutoConfiguration() {
5554

5655
@Bean
5756
@ConditionalOnMissingBean(name = { "couchbaseHealthIndicator", "couchbaseHealthContributor" })
58-
public HealthContributor couchbaseHealthContributor(Map<String, Cluster> clusters) {
59-
return createContributor(clusters);
57+
public HealthContributor couchbaseHealthContributor(ConfigurableListableBeanFactory beanFactory) {
58+
return createContributor(beanFactory, Cluster.class);
6059
}
6160

6261
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/couchbase/CouchbaseReactiveHealthContributorAutoConfiguration.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,11 +16,10 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.couchbase;
1818

19-
import java.util.Map;
20-
2119
import com.couchbase.client.java.Cluster;
2220
import reactor.core.publisher.Flux;
2321

22+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2423
import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration;
2524
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
2625
import org.springframework.boot.actuate.couchbase.CouchbaseReactiveHealthIndicator;
@@ -54,8 +53,8 @@ public CouchbaseReactiveHealthContributorAutoConfiguration() {
5453

5554
@Bean
5655
@ConditionalOnMissingBean(name = { "couchbaseHealthIndicator", "couchbaseHealthContributor" })
57-
public ReactiveHealthContributor couchbaseHealthContributor(Map<String, Cluster> clusters) {
58-
return createContributor(clusters);
56+
public ReactiveHealthContributor couchbaseHealthContributor(ConfigurableListableBeanFactory beanFactory) {
57+
return createContributor(beanFactory, Cluster.class);
5958
}
6059

6160
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/elasticsearch/ElasticsearchReactiveHealthContributorAutoConfiguration.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,10 +16,9 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.data.elasticsearch;
1818

19-
import java.util.Map;
20-
2119
import reactor.core.publisher.Flux;
2220

21+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2322
import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration;
2423
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
2524
import org.springframework.boot.actuate.data.elasticsearch.ElasticsearchReactiveHealthIndicator;
@@ -54,8 +53,8 @@ public ElasticsearchReactiveHealthContributorAutoConfiguration() {
5453

5554
@Bean
5655
@ConditionalOnMissingBean(name = { "elasticsearchHealthIndicator", "elasticsearchHealthContributor" })
57-
public ReactiveHealthContributor elasticsearchHealthContributor(Map<String, ReactiveElasticsearchClient> clients) {
58-
return createContributor(clients);
56+
public ReactiveHealthContributor elasticsearchHealthContributor(ConfigurableListableBeanFactory beanFactory) {
57+
return createContributor(beanFactory, ReactiveElasticsearchClient.class);
5958
}
6059

6160
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/mongo/MongoHealthContributorAutoConfiguration.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.data.mongo;
1818

19-
import java.util.Map;
20-
19+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2120
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
2221
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
2322
import org.springframework.boot.actuate.data.mongo.MongoHealthIndicator;
@@ -52,8 +51,8 @@ public MongoHealthContributorAutoConfiguration() {
5251

5352
@Bean
5453
@ConditionalOnMissingBean(name = { "mongoHealthIndicator", "mongoHealthContributor" })
55-
public HealthContributor mongoHealthContributor(Map<String, MongoTemplate> mongoTemplates) {
56-
return createContributor(mongoTemplates);
54+
public HealthContributor mongoHealthContributor(ConfigurableListableBeanFactory beanFactory) {
55+
return createContributor(beanFactory, MongoTemplate.class);
5756
}
5857

5958
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/mongo/MongoReactiveHealthContributorAutoConfiguration.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,10 +16,9 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.data.mongo;
1818

19-
import java.util.Map;
20-
2119
import reactor.core.publisher.Flux;
2220

21+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2322
import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration;
2423
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
2524
import org.springframework.boot.actuate.data.mongo.MongoReactiveHealthIndicator;
@@ -53,8 +52,8 @@ public MongoReactiveHealthContributorAutoConfiguration() {
5352

5453
@Bean
5554
@ConditionalOnMissingBean(name = { "mongoHealthIndicator", "mongoHealthContributor" })
56-
public ReactiveHealthContributor mongoHealthContributor(Map<String, ReactiveMongoTemplate> reactiveMongoTemplates) {
57-
return createContributor(reactiveMongoTemplates);
55+
public ReactiveHealthContributor mongoHealthContributor(ConfigurableListableBeanFactory beanFactory) {
56+
return createContributor(beanFactory, ReactiveMongoTemplate.class);
5857
}
5958

6059
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/redis/RedisHealthContributorAutoConfiguration.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,8 +16,7 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.data.redis;
1818

19-
import java.util.Map;
20-
19+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2120
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
2221
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
2322
import org.springframework.boot.actuate.data.redis.RedisHealthIndicator;
@@ -53,8 +52,8 @@ public class RedisHealthContributorAutoConfiguration
5352

5453
@Bean
5554
@ConditionalOnMissingBean(name = { "redisHealthIndicator", "redisHealthContributor" })
56-
public HealthContributor redisHealthContributor(Map<String, RedisConnectionFactory> redisConnectionFactories) {
57-
return createContributor(redisConnectionFactories);
55+
public HealthContributor redisHealthContributor(ConfigurableListableBeanFactory beanFactory) {
56+
return createContributor(beanFactory, RedisConnectionFactory.class);
5857
}
5958

6059
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/data/redis/RedisReactiveHealthContributorAutoConfiguration.java

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
2020

2121
import reactor.core.publisher.Flux;
2222

23+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2324
import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration;
2425
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
2526
import org.springframework.boot.actuate.data.redis.RedisReactiveHealthIndicator;
@@ -50,18 +51,15 @@
5051
public class RedisReactiveHealthContributorAutoConfiguration extends
5152
CompositeReactiveHealthContributorConfiguration<RedisReactiveHealthIndicator, ReactiveRedisConnectionFactory> {
5253

53-
private final Map<String, ReactiveRedisConnectionFactory> redisConnectionFactories;
54-
5554
RedisReactiveHealthContributorAutoConfiguration(
5655
Map<String, ReactiveRedisConnectionFactory> redisConnectionFactories) {
5756
super(RedisReactiveHealthIndicator::new);
58-
this.redisConnectionFactories = redisConnectionFactories;
5957
}
6058

6159
@Bean
6260
@ConditionalOnMissingBean(name = { "redisHealthIndicator", "redisHealthContributor" })
63-
public ReactiveHealthContributor redisHealthContributor() {
64-
return createContributor(this.redisConnectionFactories);
61+
public ReactiveHealthContributor redisHealthContributor(ConfigurableListableBeanFactory beanFactory) {
62+
return createContributor(beanFactory, ReactiveRedisConnectionFactory.class);
6563
}
6664

6765
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchRestHealthContributorAutoConfiguration.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,10 +16,9 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.elasticsearch;
1818

19-
import java.util.Map;
20-
2119
import org.elasticsearch.client.RestClient;
2220

21+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2322
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
2423
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
2524
import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestClientHealthIndicator;
@@ -52,8 +51,8 @@ public ElasticsearchRestHealthContributorAutoConfiguration() {
5251

5352
@Bean
5453
@ConditionalOnMissingBean(name = { "elasticsearchHealthIndicator", "elasticsearchHealthContributor" })
55-
public HealthContributor elasticsearchHealthContributor(Map<String, RestClient> clients) {
56-
return createContributor(clients);
54+
public HealthContributor elasticsearchHealthContributor(ConfigurableListableBeanFactory beanFactory) {
55+
return createContributor(beanFactory, RestClient.class);
5756
}
5857

5958
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/hazelcast/HazelcastHealthContributorAutoConfiguration.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,10 +16,9 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.hazelcast;
1818

19-
import java.util.Map;
20-
2119
import com.hazelcast.core.HazelcastInstance;
2220

21+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2322
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
2423
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
2524
import org.springframework.boot.actuate.hazelcast.HazelcastHealthIndicator;
@@ -52,8 +51,8 @@ public HazelcastHealthContributorAutoConfiguration() {
5251

5352
@Bean
5453
@ConditionalOnMissingBean(name = { "hazelcastHealthIndicator", "hazelcastHealthContributor" })
55-
public HealthContributor hazelcastHealthContributor(Map<String, HazelcastInstance> hazelcastInstances) {
56-
return createContributor(hazelcastInstances);
54+
public HealthContributor hazelcastHealthContributor(ConfigurableListableBeanFactory beanFactory) {
55+
return createContributor(beanFactory, HazelcastInstance.class);
5756
}
5857

5958
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/AbstractCompositeHealthContributorConfiguration.java

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,6 +19,8 @@
1919
import java.util.Map;
2020
import java.util.function.Function;
2121

22+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
23+
import org.springframework.beans.factory.support.SimpleAutowireCandidateResolver;
2224
import org.springframework.util.Assert;
2325

2426
/**
@@ -46,6 +48,18 @@ protected AbstractCompositeHealthContributorConfiguration(Function<B, I> indicat
4648
this.indicatorFactory = indicatorFactory;
4749
}
4850

51+
/**
52+
* Creates a composite contributor from the beans of the given {@code beanType}
53+
* retrieved from the given {@code beanFactory}.
54+
* @param beanFactory the bean factory from which the beans are retrieved
55+
* @param beanType the type of the beans that are retrieved
56+
* @return the contributor
57+
* @since 3.4.3
58+
*/
59+
protected final C createContributor(ConfigurableListableBeanFactory beanFactory, Class<B> beanType) {
60+
return createContributor(SimpleAutowireCandidateResolver.resolveAutowireCandidates(beanFactory, beanType));
61+
}
62+
4963
protected final C createContributor(Map<String, B> beans) {
5064
Assert.notEmpty(beans, "Beans must not be empty");
5165
if (beans.size() == 1) {

0 commit comments

Comments
 (0)