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
This commit is contained in:
parent
f6f0daa47d
commit
4cb9d816b9
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,9 +16,8 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.amqp;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.actuate.amqp.RabbitHealthIndicator;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
|
@ -50,8 +49,8 @@ public class RabbitHealthContributorAutoConfiguration
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "rabbitHealthIndicator", "rabbitHealthContributor" })
|
||||
public HealthContributor rabbitHealthContributor(Map<String, RabbitTemplate> rabbitTemplates) {
|
||||
return createContributor(rabbitTemplates);
|
||||
public HealthContributor rabbitHealthContributor(ConfigurableListableBeanFactory beanFactory) {
|
||||
return createContributor(beanFactory, RabbitTemplate.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,8 +16,8 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.cache;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.SimpleAutowireCandidateResolver;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure;
|
||||
import org.springframework.boot.actuate.cache.CachesEndpoint;
|
||||
|
@ -45,8 +45,9 @@ public class CachesEndpointAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public CachesEndpoint cachesEndpoint(Map<String, CacheManager> cacheManagers) {
|
||||
return new CachesEndpoint(cacheManagers);
|
||||
public CachesEndpoint cachesEndpoint(ConfigurableListableBeanFactory beanFactory) {
|
||||
return new CachesEndpoint(
|
||||
SimpleAutowireCandidateResolver.resolveAutowireCandidates(beanFactory, CacheManager.class));
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -20,6 +20,7 @@ import java.util.Map;
|
|||
|
||||
import com.datastax.oss.driver.api.core.CqlSession;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.cassandra.CassandraDriverHealthIndicator;
|
||||
|
@ -49,8 +50,8 @@ class CassandraHealthContributorConfigurations {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "cassandraHealthIndicator", "cassandraHealthContributor" })
|
||||
HealthContributor cassandraHealthContributor(Map<String, CqlSession> sessions) {
|
||||
return createContributor(sessions);
|
||||
HealthContributor cassandraHealthContributor(ConfigurableListableBeanFactory beanFactory) {
|
||||
return createContributor(beanFactory, CqlSession.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,10 +16,9 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.couchbase;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.couchbase.client.java.Cluster;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.couchbase.CouchbaseHealthIndicator;
|
||||
|
@ -55,8 +54,8 @@ public class CouchbaseHealthContributorAutoConfiguration
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "couchbaseHealthIndicator", "couchbaseHealthContributor" })
|
||||
public HealthContributor couchbaseHealthContributor(Map<String, Cluster> clusters) {
|
||||
return createContributor(clusters);
|
||||
public HealthContributor couchbaseHealthContributor(ConfigurableListableBeanFactory beanFactory) {
|
||||
return createContributor(beanFactory, Cluster.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,11 +16,10 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.couchbase;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.couchbase.client.java.Cluster;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.couchbase.CouchbaseReactiveHealthIndicator;
|
||||
|
@ -54,8 +53,8 @@ public class CouchbaseReactiveHealthContributorAutoConfiguration
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "couchbaseHealthIndicator", "couchbaseHealthContributor" })
|
||||
public ReactiveHealthContributor couchbaseHealthContributor(Map<String, Cluster> clusters) {
|
||||
return createContributor(clusters);
|
||||
public ReactiveHealthContributor couchbaseHealthContributor(ConfigurableListableBeanFactory beanFactory) {
|
||||
return createContributor(beanFactory, Cluster.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,10 +16,9 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.data.elasticsearch;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.data.elasticsearch.ElasticsearchReactiveHealthIndicator;
|
||||
|
@ -54,8 +53,8 @@ public class ElasticsearchReactiveHealthContributorAutoConfiguration extends
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "elasticsearchHealthIndicator", "elasticsearchHealthContributor" })
|
||||
public ReactiveHealthContributor elasticsearchHealthContributor(Map<String, ReactiveElasticsearchClient> clients) {
|
||||
return createContributor(clients);
|
||||
public ReactiveHealthContributor elasticsearchHealthContributor(ConfigurableListableBeanFactory beanFactory) {
|
||||
return createContributor(beanFactory, ReactiveElasticsearchClient.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,8 +16,7 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.data.mongo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.data.mongo.MongoHealthIndicator;
|
||||
|
@ -52,8 +51,8 @@ public class MongoHealthContributorAutoConfiguration
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "mongoHealthIndicator", "mongoHealthContributor" })
|
||||
public HealthContributor mongoHealthContributor(Map<String, MongoTemplate> mongoTemplates) {
|
||||
return createContributor(mongoTemplates);
|
||||
public HealthContributor mongoHealthContributor(ConfigurableListableBeanFactory beanFactory) {
|
||||
return createContributor(beanFactory, MongoTemplate.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,10 +16,9 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.data.mongo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.data.mongo.MongoReactiveHealthIndicator;
|
||||
|
@ -53,8 +52,8 @@ public class MongoReactiveHealthContributorAutoConfiguration
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "mongoHealthIndicator", "mongoHealthContributor" })
|
||||
public ReactiveHealthContributor mongoHealthContributor(Map<String, ReactiveMongoTemplate> reactiveMongoTemplates) {
|
||||
return createContributor(reactiveMongoTemplates);
|
||||
public ReactiveHealthContributor mongoHealthContributor(ConfigurableListableBeanFactory beanFactory) {
|
||||
return createContributor(beanFactory, ReactiveMongoTemplate.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,8 +16,7 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.data.redis;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.data.redis.RedisHealthIndicator;
|
||||
|
@ -53,8 +52,8 @@ public class RedisHealthContributorAutoConfiguration
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "redisHealthIndicator", "redisHealthContributor" })
|
||||
public HealthContributor redisHealthContributor(Map<String, RedisConnectionFactory> redisConnectionFactories) {
|
||||
return createContributor(redisConnectionFactories);
|
||||
public HealthContributor redisHealthContributor(ConfigurableListableBeanFactory beanFactory) {
|
||||
return createContributor(beanFactory, RedisConnectionFactory.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -20,6 +20,7 @@ import java.util.Map;
|
|||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.data.redis.RedisReactiveHealthIndicator;
|
||||
|
@ -50,18 +51,15 @@ import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory;
|
|||
public class RedisReactiveHealthContributorAutoConfiguration extends
|
||||
CompositeReactiveHealthContributorConfiguration<RedisReactiveHealthIndicator, ReactiveRedisConnectionFactory> {
|
||||
|
||||
private final Map<String, ReactiveRedisConnectionFactory> redisConnectionFactories;
|
||||
|
||||
RedisReactiveHealthContributorAutoConfiguration(
|
||||
Map<String, ReactiveRedisConnectionFactory> redisConnectionFactories) {
|
||||
super(RedisReactiveHealthIndicator::new);
|
||||
this.redisConnectionFactories = redisConnectionFactories;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "redisHealthIndicator", "redisHealthContributor" })
|
||||
public ReactiveHealthContributor redisHealthContributor() {
|
||||
return createContributor(this.redisConnectionFactories);
|
||||
public ReactiveHealthContributor redisHealthContributor(ConfigurableListableBeanFactory beanFactory) {
|
||||
return createContributor(beanFactory, ReactiveRedisConnectionFactory.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,10 +16,9 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.elasticsearch;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.elasticsearch.client.RestClient;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestClientHealthIndicator;
|
||||
|
@ -52,8 +51,8 @@ public class ElasticsearchRestHealthContributorAutoConfiguration
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "elasticsearchHealthIndicator", "elasticsearchHealthContributor" })
|
||||
public HealthContributor elasticsearchHealthContributor(Map<String, RestClient> clients) {
|
||||
return createContributor(clients);
|
||||
public HealthContributor elasticsearchHealthContributor(ConfigurableListableBeanFactory beanFactory) {
|
||||
return createContributor(beanFactory, RestClient.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,10 +16,9 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.hazelcast;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.hazelcast.HazelcastHealthIndicator;
|
||||
|
@ -52,8 +51,8 @@ public class HazelcastHealthContributorAutoConfiguration
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "hazelcastHealthIndicator", "hazelcastHealthContributor" })
|
||||
public HealthContributor hazelcastHealthContributor(Map<String, HazelcastInstance> hazelcastInstances) {
|
||||
return createContributor(hazelcastInstances);
|
||||
public HealthContributor hazelcastHealthContributor(ConfigurableListableBeanFactory beanFactory) {
|
||||
return createContributor(beanFactory, HazelcastInstance.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -19,6 +19,8 @@ package org.springframework.boot.actuate.autoconfigure.health;
|
|||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.SimpleAutowireCandidateResolver;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
|
@ -46,6 +48,18 @@ public abstract class AbstractCompositeHealthContributorConfiguration<C, I exten
|
|||
this.indicatorFactory = indicatorFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a composite contributor from the beans of the given {@code beanType}
|
||||
* retrieved from the given {@code beanFactory}.
|
||||
* @param beanFactory the bean factory from which the beans are retrieved
|
||||
* @param beanType the type of the beans that are retrieved
|
||||
* @return the contributor
|
||||
* @since 3.4.3
|
||||
*/
|
||||
protected final C createContributor(ConfigurableListableBeanFactory beanFactory, Class<B> beanType) {
|
||||
return createContributor(SimpleAutowireCandidateResolver.resolveAutowireCandidates(beanFactory, beanType));
|
||||
}
|
||||
|
||||
protected final C createContributor(Map<String, B> beans) {
|
||||
Assert.notEmpty(beans, "Beans must not be empty");
|
||||
if (beans.size() == 1) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -28,6 +28,8 @@ import javax.sql.DataSource;
|
|||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.SimpleAutowireCandidateResolver;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.CompositeHealthContributor;
|
||||
import org.springframework.boot.actuate.health.HealthContributor;
|
||||
|
@ -84,8 +86,10 @@ public class DataSourceHealthContributorAutoConfiguration implements Initializin
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "dbHealthIndicator", "dbHealthContributor" })
|
||||
public HealthContributor dbHealthContributor(Map<String, DataSource> dataSources,
|
||||
public HealthContributor dbHealthContributor(ConfigurableListableBeanFactory beanFactory,
|
||||
DataSourceHealthIndicatorProperties dataSourceHealthIndicatorProperties) {
|
||||
Map<String, DataSource> dataSources = SimpleAutowireCandidateResolver.resolveAutowireCandidates(beanFactory,
|
||||
DataSource.class);
|
||||
if (dataSourceHealthIndicatorProperties.isIgnoreRoutingDataSources()) {
|
||||
Map<String, DataSource> filteredDatasources = dataSources.entrySet()
|
||||
.stream()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,10 +16,9 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.jms;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.jms.ConnectionFactory;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.HealthContributor;
|
||||
|
@ -52,8 +51,8 @@ public class JmsHealthContributorAutoConfiguration
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "jmsHealthIndicator", "jmsHealthContributor" })
|
||||
public HealthContributor jmsHealthContributor(Map<String, ConnectionFactory> connectionFactories) {
|
||||
return createContributor(connectionFactories);
|
||||
public HealthContributor jmsHealthContributor(ConfigurableListableBeanFactory beanFactory) {
|
||||
return createContributor(beanFactory, ConnectionFactory.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,8 +16,7 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.ldap;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.HealthContributor;
|
||||
|
@ -51,8 +50,8 @@ public class LdapHealthContributorAutoConfiguration
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "ldapHealthIndicator", "ldapHealthContributor" })
|
||||
public HealthContributor ldapHealthContributor(Map<String, LdapOperations> ldapOperations) {
|
||||
return createContributor(ldapOperations);
|
||||
public HealthContributor ldapHealthContributor(ConfigurableListableBeanFactory beanFactory) {
|
||||
return createContributor(beanFactory, LdapOperations.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,8 +16,7 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.mail;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.HealthContributor;
|
||||
|
@ -50,8 +49,8 @@ public class MailHealthContributorAutoConfiguration
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "mailHealthIndicator", "mailHealthContributor" })
|
||||
public HealthContributor mailHealthContributor(Map<String, JavaMailSenderImpl> mailSenders) {
|
||||
return createContributor(mailSenders);
|
||||
public HealthContributor mailHealthContributor(ConfigurableListableBeanFactory beanFactory) {
|
||||
return createContributor(beanFactory, JavaMailSenderImpl.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -22,6 +22,8 @@ import java.util.Map;
|
|||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.SimpleAutowireCandidateResolver;
|
||||
import org.springframework.boot.actuate.metrics.cache.CacheMeterBinderProvider;
|
||||
import org.springframework.boot.actuate.metrics.cache.CacheMetricsRegistrar;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
|
@ -50,9 +52,9 @@ class CacheMetricsRegistrarConfiguration {
|
|||
private final Map<String, CacheManager> cacheManagers;
|
||||
|
||||
CacheMetricsRegistrarConfiguration(MeterRegistry registry, Collection<CacheMeterBinderProvider<?>> binderProviders,
|
||||
Map<String, CacheManager> cacheManagers) {
|
||||
ConfigurableListableBeanFactory beanFactory) {
|
||||
this.registry = registry;
|
||||
this.cacheManagers = cacheManagers;
|
||||
this.cacheManagers = SimpleAutowireCandidateResolver.resolveAutowireCandidates(beanFactory, CacheManager.class);
|
||||
this.cacheMetricsRegistrar = new CacheMetricsRegistrar(this.registry, binderProviders);
|
||||
bindCachesToRegistry();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -32,6 +32,8 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.SimpleAutowireCandidateResolver;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
|
||||
import org.springframework.boot.actuate.metrics.jdbc.DataSourcePoolMetrics;
|
||||
|
@ -67,9 +69,11 @@ public class DataSourcePoolMetricsAutoConfiguration {
|
|||
private static final String DATASOURCE_SUFFIX = "dataSource";
|
||||
|
||||
@Bean
|
||||
DataSourcePoolMetadataMeterBinder dataSourcePoolMetadataMeterBinder(Map<String, DataSource> dataSources,
|
||||
DataSourcePoolMetadataMeterBinder dataSourcePoolMetadataMeterBinder(ConfigurableListableBeanFactory beanFactory,
|
||||
ObjectProvider<DataSourcePoolMetadataProvider> metadataProviders) {
|
||||
return new DataSourcePoolMetadataMeterBinder(dataSources, metadataProviders);
|
||||
return new DataSourcePoolMetadataMeterBinder(
|
||||
SimpleAutowireCandidateResolver.resolveAutowireCandidates(beanFactory, DataSource.class),
|
||||
metadataProviders);
|
||||
}
|
||||
|
||||
static class DataSourcePoolMetadataMeterBinder implements MeterBinder {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -26,6 +26,8 @@ import org.hibernate.SessionFactory;
|
|||
import org.hibernate.stat.HibernateMetrics;
|
||||
|
||||
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.SimpleAutowireCandidateResolver;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
|
@ -57,9 +59,9 @@ public class HibernateMetricsAutoConfiguration implements SmartInitializingSingl
|
|||
|
||||
private final MeterRegistry meterRegistry;
|
||||
|
||||
public HibernateMetricsAutoConfiguration(Map<String, EntityManagerFactory> entityManagerFactories,
|
||||
MeterRegistry meterRegistry) {
|
||||
this.entityManagerFactories = entityManagerFactories;
|
||||
public HibernateMetricsAutoConfiguration(ConfigurableListableBeanFactory beanFactory, MeterRegistry meterRegistry) {
|
||||
this.entityManagerFactories = SimpleAutowireCandidateResolver.resolveAutowireCandidates(beanFactory,
|
||||
EntityManagerFactory.class);
|
||||
this.meterRegistry = meterRegistry;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,8 +16,6 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.metrics.r2dbc;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.Tags;
|
||||
import io.r2dbc.pool.ConnectionPool;
|
||||
|
@ -25,6 +23,8 @@ import io.r2dbc.spi.ConnectionFactory;
|
|||
import io.r2dbc.spi.Wrapped;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.SimpleAutowireCandidateResolver;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
|
||||
import org.springframework.boot.actuate.metrics.r2dbc.ConnectionPoolMetrics;
|
||||
|
@ -49,14 +49,14 @@ import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
|
|||
public class ConnectionPoolMetricsAutoConfiguration {
|
||||
|
||||
@Autowired
|
||||
public void bindConnectionPoolsToRegistry(Map<String, ConnectionFactory> connectionFactories,
|
||||
MeterRegistry registry) {
|
||||
connectionFactories.forEach((beanName, connectionFactory) -> {
|
||||
ConnectionPool pool = extractPool(connectionFactory);
|
||||
if (pool != null) {
|
||||
new ConnectionPoolMetrics(pool, beanName, Tags.empty()).bindTo(registry);
|
||||
}
|
||||
});
|
||||
public void bindConnectionPoolsToRegistry(ConfigurableListableBeanFactory beanFactory, MeterRegistry registry) {
|
||||
SimpleAutowireCandidateResolver.resolveAutowireCandidates(beanFactory, ConnectionFactory.class)
|
||||
.forEach((beanName, connectionFactory) -> {
|
||||
ConnectionPool pool = extractPool(connectionFactory);
|
||||
if (pool != null) {
|
||||
new ConnectionPoolMetrics(pool, beanName, Tags.empty()).bindTo(registry);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private ConnectionPool extractPool(Object candidate) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -17,7 +17,6 @@
|
|||
package org.springframework.boot.actuate.autoconfigure.metrics.task;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
|
@ -25,6 +24,8 @@ import io.micrometer.core.instrument.MeterRegistry;
|
|||
import io.micrometer.core.instrument.binder.jvm.ExecutorServiceMetrics;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.SimpleAutowireCandidateResolver;
|
||||
import org.springframework.boot.LazyInitializationExcludeFilter;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
|
||||
|
@ -35,6 +36,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
|||
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||
|
||||
|
@ -54,15 +56,16 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
|||
public class TaskExecutorMetricsAutoConfiguration {
|
||||
|
||||
@Autowired
|
||||
public void bindTaskExecutorsToRegistry(Map<String, Executor> executors, MeterRegistry registry) {
|
||||
executors.forEach((beanName, executor) -> {
|
||||
if (executor instanceof ThreadPoolTaskExecutor threadPoolTaskExecutor) {
|
||||
monitor(registry, safeGetThreadPoolExecutor(threadPoolTaskExecutor), beanName);
|
||||
}
|
||||
else if (executor instanceof ThreadPoolTaskScheduler threadPoolTaskScheduler) {
|
||||
monitor(registry, safeGetThreadPoolExecutor(threadPoolTaskScheduler), beanName);
|
||||
}
|
||||
});
|
||||
public void bindTaskExecutorsToRegistry(ConfigurableListableBeanFactory beanFactory, MeterRegistry registry) {
|
||||
SimpleAutowireCandidateResolver.resolveAutowireCandidates(beanFactory, TaskExecutor.class)
|
||||
.forEach((beanName, executor) -> {
|
||||
if (executor instanceof ThreadPoolTaskExecutor threadPoolTaskExecutor) {
|
||||
monitor(registry, safeGetThreadPoolExecutor(threadPoolTaskExecutor), beanName);
|
||||
}
|
||||
else if (executor instanceof ThreadPoolTaskScheduler threadPoolTaskScheduler) {
|
||||
monitor(registry, safeGetThreadPoolExecutor(threadPoolTaskScheduler), beanName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,11 +16,10 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.neo4j;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.neo4j.driver.Driver;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.health.HealthContributor;
|
||||
|
@ -49,8 +48,8 @@ class Neo4jHealthContributorConfigurations {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "neo4jHealthIndicator", "neo4jHealthContributor" })
|
||||
HealthContributor neo4jHealthContributor(Map<String, Driver> drivers) {
|
||||
return createContributor(drivers);
|
||||
HealthContributor neo4jHealthContributor(ConfigurableListableBeanFactory beanFactory) {
|
||||
return createContributor(beanFactory, Driver.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -66,8 +65,8 @@ class Neo4jHealthContributorConfigurations {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "neo4jHealthIndicator", "neo4jHealthContributor" })
|
||||
ReactiveHealthContributor neo4jHealthContributor(Map<String, Driver> drivers) {
|
||||
return createContributor(drivers);
|
||||
ReactiveHealthContributor neo4jHealthContributor(ConfigurableListableBeanFactory beanFactory) {
|
||||
return createContributor(beanFactory, Driver.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,10 +16,9 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.r2dbc;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.r2dbc.spi.ConnectionFactory;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.ReactiveHealthContributor;
|
||||
|
@ -46,17 +45,14 @@ import org.springframework.context.annotation.Bean;
|
|||
public class ConnectionFactoryHealthContributorAutoConfiguration
|
||||
extends CompositeReactiveHealthContributorConfiguration<ConnectionFactoryHealthIndicator, ConnectionFactory> {
|
||||
|
||||
private final Map<String, ConnectionFactory> connectionFactory;
|
||||
|
||||
ConnectionFactoryHealthContributorAutoConfiguration(Map<String, ConnectionFactory> connectionFactory) {
|
||||
ConnectionFactoryHealthContributorAutoConfiguration() {
|
||||
super(ConnectionFactoryHealthIndicator::new);
|
||||
this.connectionFactory = connectionFactory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = { "r2dbcHealthIndicator", "r2dbcHealthContributor" })
|
||||
public ReactiveHealthContributor r2dbcHealthContributor() {
|
||||
return createContributor(this.connectionFactory);
|
||||
public ReactiveHealthContributor r2dbcHealthContributor(ConfigurableListableBeanFactory beanFactory) {
|
||||
return createContributor(beanFactory, ConnectionFactory.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -23,6 +23,11 @@ import java.util.Map;
|
|||
import io.lettuce.core.dynamic.support.ResolvableType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.health.NamedContributor;
|
||||
import org.springframework.boot.actuate.health.NamedContributors;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
@ -69,10 +74,80 @@ abstract class AbstractCompositeHealthContributorConfigurationTests<C, I extends
|
|||
assertThat(ClassUtils.getShortName(contributor.getClass())).startsWith("Composite");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createContributorWhenBeanFactoryHasNoBeansThrowsException() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
|
||||
context.refresh();
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> newComposite().createContributor(context.getBeanFactory(), TestBean.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void createContributorWhenBeanFactoryHasSingleBeanCreatesIndicator() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
|
||||
context.register(SingleBeanConfiguration.class);
|
||||
context.refresh();
|
||||
C contributor = newComposite().createContributor(context.getBeanFactory(), TestBean.class);
|
||||
assertThat(contributor).isInstanceOf(this.indicatorType);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void createContributorWhenBeanFactoryHasMultipleBeansCreatesComposite() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
|
||||
context.register(MultipleBeansConfiguration.class);
|
||||
context.refresh();
|
||||
C contributor = newComposite().createContributor(context.getBeanFactory(), TestBean.class);
|
||||
assertThat(contributor).isNotInstanceOf(this.indicatorType);
|
||||
assertThat(ClassUtils.getShortName(contributor.getClass())).startsWith("Composite");
|
||||
assertThat(((NamedContributors<?>) contributor).stream().map(NamedContributor::getName))
|
||||
.containsExactlyInAnyOrder("standard", "nonDefault");
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract AbstractCompositeHealthContributorConfiguration<C, I, TestBean> newComposite();
|
||||
|
||||
static class TestBean {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class MultipleBeansConfiguration {
|
||||
|
||||
@Bean
|
||||
TestBean standard() {
|
||||
return new TestBean();
|
||||
}
|
||||
|
||||
@Bean(defaultCandidate = false)
|
||||
TestBean nonDefault() {
|
||||
return new TestBean();
|
||||
|
||||
}
|
||||
|
||||
@Bean(autowireCandidate = false)
|
||||
TestBean nonAutowire() {
|
||||
return new TestBean();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class SingleBeanConfiguration {
|
||||
|
||||
@Bean
|
||||
TestBean standard() {
|
||||
return new TestBean();
|
||||
}
|
||||
|
||||
@Bean(autowireCandidate = false)
|
||||
TestBean nonAutowire() {
|
||||
return new TestBean();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -70,12 +70,14 @@ class DataSourceHealthContributorAutoConfigurationTests {
|
|||
|
||||
@Test
|
||||
void runWhenMultipleDataSourceBeansShouldCreateCompositeIndicator() {
|
||||
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class, DataSourceConfig.class)
|
||||
this.contextRunner
|
||||
.withUserConfiguration(EmbeddedDataSourceConfiguration.class, DataSourceConfig.class,
|
||||
NonStandardDataSourceConfig.class)
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(CompositeHealthContributor.class);
|
||||
CompositeHealthContributor contributor = context.getBean(CompositeHealthContributor.class);
|
||||
String[] names = contributor.stream().map(NamedContributor::getName).toArray(String[]::new);
|
||||
assertThat(names).containsExactlyInAnyOrder("dataSource", "testDataSource");
|
||||
assertThat(names).containsExactlyInAnyOrder("dataSource", "standardDataSource", "nonDefaultDataSource");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -217,7 +219,7 @@ class DataSourceHealthContributorAutoConfigurationTests {
|
|||
|
||||
@Bean
|
||||
@ConfigurationProperties(prefix = "spring.datasource.test")
|
||||
DataSource testDataSource() {
|
||||
DataSource standardDataSource() {
|
||||
return DataSourceBuilder.create()
|
||||
.type(org.apache.tomcat.jdbc.pool.DataSource.class)
|
||||
.driverClassName("org.hsqldb.jdbc.JDBCDriver")
|
||||
|
@ -228,6 +230,34 @@ class DataSourceHealthContributorAutoConfigurationTests {
|
|||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties
|
||||
static class NonStandardDataSourceConfig {
|
||||
|
||||
@Bean(defaultCandidate = false)
|
||||
@ConfigurationProperties(prefix = "spring.datasource.non-default")
|
||||
DataSource nonDefaultDataSource() {
|
||||
return DataSourceBuilder.create()
|
||||
.type(org.apache.tomcat.jdbc.pool.DataSource.class)
|
||||
.driverClassName("org.hsqldb.jdbc.JDBCDriver")
|
||||
.url("jdbc:hsqldb:mem:non-default")
|
||||
.username("sa")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean(autowireCandidate = false)
|
||||
@ConfigurationProperties(prefix = "spring.datasource.non-autowire")
|
||||
DataSource nonAutowireDataSource() {
|
||||
return DataSourceBuilder.create()
|
||||
.type(org.apache.tomcat.jdbc.pool.DataSource.class)
|
||||
.driverClassName("org.hsqldb.jdbc.JDBCDriver")
|
||||
.url("jdbc:hsqldb:mem:non-autowire")
|
||||
.username("sa")
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class RoutingDataSourceConfig {
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,6 +16,10 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.metrics.cache;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.CaffeineSpec;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -23,7 +27,12 @@ import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun;
|
|||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.CachingConfigurer;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.cache.caffeine.CaffeineCacheManager;
|
||||
import org.springframework.cache.interceptor.CacheResolver;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
@ -91,6 +100,54 @@ class CacheMetricsAutoConfigurationTests {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void customCacheManagersAreInstrumented() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.cache.type=caffeine", "spring.cache.cache-names=cache1,cache2",
|
||||
"spring.cache.caffeine.spec=recordStats")
|
||||
.withUserConfiguration(CustomCacheManagersConfiguration.class)
|
||||
.run((context) -> {
|
||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||
assertThat(registry.find("cache.gets").meters()).map((meter) -> meter.getId().getTag("cache"))
|
||||
.containsOnly("standard", "non-default");
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomCacheManagersConfiguration implements CachingConfigurer {
|
||||
|
||||
@Bean
|
||||
CacheManager standardCacheManager() {
|
||||
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
|
||||
cacheManager.setCaffeineSpec(CaffeineSpec.parse("recordStats"));
|
||||
cacheManager.setCacheNames(List.of("standard"));
|
||||
return cacheManager;
|
||||
}
|
||||
|
||||
@Bean(defaultCandidate = false)
|
||||
CacheManager nonDefaultCacheManager() {
|
||||
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
|
||||
cacheManager.setCaffeineSpec(CaffeineSpec.parse("recordStats"));
|
||||
cacheManager.setCacheNames(List.of("non-default"));
|
||||
return cacheManager;
|
||||
}
|
||||
|
||||
@Bean(autowireCandidate = false)
|
||||
CacheManager nonAutowireCacheManager() {
|
||||
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
|
||||
cacheManager.setCaffeineSpec(CaffeineSpec.parse("recordStats"));
|
||||
cacheManager.setCacheNames(List.of("non-autowire"));
|
||||
return cacheManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public CacheResolver cacheResolver() {
|
||||
return (context) -> Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableCaching
|
||||
static class CachingConfiguration {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -86,11 +86,11 @@ class DataSourcePoolMetricsAutoConfigurationTests {
|
|||
this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||
.withUserConfiguration(TwoDataSourcesConfiguration.class)
|
||||
.run((context) -> {
|
||||
context.getBean("firstDataSource", DataSource.class).getConnection().getMetaData();
|
||||
context.getBean("secondOne", DataSource.class).getConnection().getMetaData();
|
||||
context.getBean("nonDefaultDataSource", DataSource.class).getConnection().getMetaData();
|
||||
context.getBean("nonAutowireDataSource", DataSource.class).getConnection().getMetaData();
|
||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||
registry.get("jdbc.connections.max").tags("name", "first").meter();
|
||||
registry.get("jdbc.connections.max").tags("name", "secondOne").meter();
|
||||
assertThat(registry.find("jdbc.connections.max").meters()).map((meter) -> meter.getId().getTag("name"))
|
||||
.containsOnly("dataSource", "nonDefault");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -101,11 +101,11 @@ class DataSourcePoolMetricsAutoConfigurationTests {
|
|||
(context) -> context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor()))
|
||||
.withUserConfiguration(TwoDataSourcesConfiguration.class)
|
||||
.run((context) -> {
|
||||
context.getBean("firstDataSource", DataSource.class).getConnection().getMetaData();
|
||||
context.getBean("secondOne", DataSource.class).getConnection().getMetaData();
|
||||
context.getBean("nonDefaultDataSource", DataSource.class).getConnection().getMetaData();
|
||||
context.getBean("nonAutowireDataSource", DataSource.class).getConnection().getMetaData();
|
||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||
registry.get("jdbc.connections.max").tags("name", "first").meter();
|
||||
registry.get("jdbc.connections.max").tags("name", "secondOne").meter();
|
||||
assertThat(registry.find("jdbc.connections.max").meters()).map((meter) -> meter.getId().getTag("name"))
|
||||
.containsOnly("dataSource", "nonDefault");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -239,13 +239,13 @@ class DataSourcePoolMetricsAutoConfigurationTests {
|
|||
@Configuration(proxyBeanMethods = false)
|
||||
static class TwoDataSourcesConfiguration {
|
||||
|
||||
@Bean
|
||||
DataSource firstDataSource() {
|
||||
@Bean(defaultCandidate = false)
|
||||
DataSource nonDefaultDataSource() {
|
||||
return createDataSource();
|
||||
}
|
||||
|
||||
@Bean
|
||||
DataSource secondOne() {
|
||||
@Bean(autowireCandidate = false)
|
||||
DataSource nonAutowireDataSource() {
|
||||
return createDataSource();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -101,13 +101,15 @@ class HibernateMetricsAutoConfigurationTests {
|
|||
@Test
|
||||
void allEntityManagerFactoriesCanBeInstrumented() {
|
||||
this.contextRunner.withPropertyValues("spring.jpa.properties.hibernate.generate_statistics:true")
|
||||
.withUserConfiguration(TwoEntityManagerFactoriesConfiguration.class)
|
||||
.withUserConfiguration(MultipleEntityManagerFactoriesConfiguration.class)
|
||||
.run((context) -> {
|
||||
context.getBean("firstEntityManagerFactory", EntityManagerFactory.class).unwrap(SessionFactory.class);
|
||||
context.getBean("secondOne", EntityManagerFactory.class).unwrap(SessionFactory.class);
|
||||
context.getBean("nonDefault", EntityManagerFactory.class).unwrap(SessionFactory.class);
|
||||
context.getBean("nonAutowire", EntityManagerFactory.class).unwrap(SessionFactory.class);
|
||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||
registry.get("hibernate.statements").tags("entityManagerFactory", "first").meter();
|
||||
registry.get("hibernate.statements").tags("entityManagerFactory", "secondOne").meter();
|
||||
assertThat(registry.find("hibernate.statements").meters())
|
||||
.map((meter) -> meter.getId().getTag("entityManagerFactory"))
|
||||
.containsOnly("first", "nonDefault");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -171,7 +173,7 @@ class HibernateMetricsAutoConfigurationTests {
|
|||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TwoEntityManagerFactoriesConfiguration {
|
||||
static class MultipleEntityManagerFactoriesConfiguration {
|
||||
|
||||
private static final Class<?>[] PACKAGE_CLASSES = new Class<?>[] { MyEntity.class };
|
||||
|
||||
|
@ -181,8 +183,13 @@ class HibernateMetricsAutoConfigurationTests {
|
|||
return createSessionFactory(ds);
|
||||
}
|
||||
|
||||
@Bean
|
||||
LocalContainerEntityManagerFactoryBean secondOne(DataSource ds) {
|
||||
@Bean(defaultCandidate = false)
|
||||
LocalContainerEntityManagerFactoryBean nonDefault(DataSource ds) {
|
||||
return createSessionFactory(ds);
|
||||
}
|
||||
|
||||
@Bean(autowireCandidate = false)
|
||||
LocalContainerEntityManagerFactoryBean nonAutowire(DataSource ds) {
|
||||
return createSessionFactory(ds);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -109,11 +109,10 @@ class ConnectionPoolMetricsAutoConfigurationTests {
|
|||
|
||||
@Test
|
||||
void allConnectionPoolsCanBeInstrumented() {
|
||||
this.contextRunner.withUserConfiguration(TwoConnectionPoolsConfiguration.class).run((context) -> {
|
||||
this.contextRunner.withUserConfiguration(MultipleConnectionPoolsConfiguration.class).run((context) -> {
|
||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||
assertThat(registry.find("r2dbc.pool.acquired").gauges()).extracting(Meter::getId)
|
||||
.extracting((id) -> id.getTag("name"))
|
||||
.containsExactlyInAnyOrder("firstPool", "secondPool");
|
||||
assertThat(registry.find("r2dbc.pool.acquired").meters()).map((meter) -> meter.getId().getTag("name"))
|
||||
.containsOnly("standardPool", "nonDefaultPool");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -179,7 +178,7 @@ class ConnectionPoolMetricsAutoConfigurationTests {
|
|||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TwoConnectionPoolsConfiguration {
|
||||
static class MultipleConnectionPoolsConfiguration {
|
||||
|
||||
@Bean
|
||||
CloseableConnectionFactory connectionFactory() {
|
||||
|
@ -188,12 +187,17 @@ class ConnectionPoolMetricsAutoConfigurationTests {
|
|||
}
|
||||
|
||||
@Bean
|
||||
ConnectionPool firstPool(ConnectionFactory connectionFactory) {
|
||||
ConnectionPool standardPool(ConnectionFactory connectionFactory) {
|
||||
return new ConnectionPool(ConnectionPoolConfiguration.builder(connectionFactory).build());
|
||||
}
|
||||
|
||||
@Bean
|
||||
ConnectionPool secondPool(ConnectionFactory connectionFactory) {
|
||||
@Bean(defaultCandidate = false)
|
||||
ConnectionPool nonDefaultPool(ConnectionFactory connectionFactory) {
|
||||
return new ConnectionPool(ConnectionPoolConfiguration.builder(connectionFactory).build());
|
||||
}
|
||||
|
||||
@Bean(autowireCandidate = false)
|
||||
ConnectionPool nonAutowirePool(ConnectionFactory connectionFactory) {
|
||||
return new ConnectionPool(ConnectionPoolConfiguration.builder(connectionFactory).build());
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -17,7 +17,6 @@
|
|||
package org.springframework.boot.actuate.autoconfigure.metrics.task;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import io.micrometer.core.instrument.FunctionCounter;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
|
@ -30,6 +29,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
|
|||
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
@ -82,14 +82,12 @@ class TaskExecutorMetricsAutoConfigurationTests {
|
|||
|
||||
@Test
|
||||
void taskExecutorsWithCustomNamesAreInstrumented() {
|
||||
this.contextRunner.withBean("firstTaskExecutor", Executor.class, ThreadPoolTaskExecutor::new)
|
||||
.withBean("customName", ThreadPoolTaskExecutor.class, ThreadPoolTaskExecutor::new)
|
||||
.run((context) -> {
|
||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||
Collection<FunctionCounter> meters = registry.get("executor.completed").functionCounters();
|
||||
assertThat(meters).map((meter) -> meter.getId().getTag("name"))
|
||||
.containsExactlyInAnyOrder("firstTaskExecutor", "customName");
|
||||
});
|
||||
this.contextRunner.withUserConfiguration(MultipleTaskExecutorsConfiguration.class).run((context) -> {
|
||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||
Collection<FunctionCounter> meters = registry.get("executor.completed").functionCounters();
|
||||
assertThat(meters).map((meter) -> meter.getId().getTag("name"))
|
||||
.containsExactlyInAnyOrder("standardTaskExecutor", "nonDefault");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -134,14 +132,12 @@ class TaskExecutorMetricsAutoConfigurationTests {
|
|||
|
||||
@Test
|
||||
void taskSchedulersWithCustomNamesAreInstrumented() {
|
||||
this.contextRunner.withBean("firstTaskScheduler", Executor.class, ThreadPoolTaskScheduler::new)
|
||||
.withBean("customName", ThreadPoolTaskScheduler.class, ThreadPoolTaskScheduler::new)
|
||||
.run((context) -> {
|
||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||
Collection<FunctionCounter> meters = registry.get("executor.completed").functionCounters();
|
||||
assertThat(meters).map((meter) -> meter.getId().getTag("name"))
|
||||
.containsExactlyInAnyOrder("firstTaskScheduler", "customName");
|
||||
});
|
||||
this.contextRunner.withUserConfiguration(MultipleTaskSchedulersConfiguration.class).run((context) -> {
|
||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||
Collection<FunctionCounter> meters = registry.get("executor.completed").functionCounters();
|
||||
assertThat(meters).map((meter) -> meter.getId().getTag("name"))
|
||||
.containsExactlyInAnyOrder("standardTaskScheduler", "nonDefault");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -176,4 +172,44 @@ class TaskExecutorMetricsAutoConfigurationTests {
|
|||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class MultipleTaskSchedulersConfiguration {
|
||||
|
||||
@Bean
|
||||
ThreadPoolTaskScheduler standardTaskScheduler() {
|
||||
return new ThreadPoolTaskScheduler();
|
||||
}
|
||||
|
||||
@Bean(defaultCandidate = false)
|
||||
ThreadPoolTaskScheduler nonDefault() {
|
||||
return new ThreadPoolTaskScheduler();
|
||||
}
|
||||
|
||||
@Bean(autowireCandidate = false)
|
||||
ThreadPoolTaskScheduler nonAutowire() {
|
||||
return new ThreadPoolTaskScheduler();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class MultipleTaskExecutorsConfiguration {
|
||||
|
||||
@Bean
|
||||
ThreadPoolTaskExecutor standardTaskExecutor() {
|
||||
return new ThreadPoolTaskExecutor();
|
||||
}
|
||||
|
||||
@Bean(defaultCandidate = false)
|
||||
ThreadPoolTaskExecutor nonDefault() {
|
||||
return new ThreadPoolTaskExecutor();
|
||||
}
|
||||
|
||||
@Bean(autowireCandidate = false)
|
||||
ThreadPoolTaskExecutor nonAutowire() {
|
||||
return new ThreadPoolTaskExecutor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue