Skip to content

Commit 72b9e70

Browse files
artembilangaryrussell
authored andcommitted
GH-3643: Defer MeterRegistry bean dependency
Fixes #3643 The `ImportBeanDefinitionRegistrar` register its bean definition in the early phase. It causes a problem with Spring Boot when an explicit `@EnableIntegrationManagement` is declared: the `MeterRegistry` is provided later on via auto-configuration and `MicrometerMetricsCaptor` has no knowledge about `MeterRegistry` at the `ImportBeanDefinitionRegistrar` phase. * Reworks `MicrometerMetricsCaptorRegistrar` to the `MicrometerMetricsCaptorConfiguration` and use special conditional `MicrometerMetricsCaptorImportSelector` for that `@EnableIntegrationManagement`. This way a `MicrometerMetricsCaptor` `@Bean` consults `ObjectProvider<MeterRegistry>` on its creating time and returns `null` if no `MeterRegistry` beans at all.
1 parent a03af08 commit 72b9e70

File tree

4 files changed

+59
-23
lines changed

4 files changed

+59
-23
lines changed

spring-integration-core/src/main/java/org/springframework/integration/config/EnableIntegrationManagement.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2020 the original author or authors.
2+
* Copyright 2014-2021 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.
@@ -23,7 +23,7 @@
2323
import java.lang.annotation.Target;
2424

2525
import org.springframework.context.annotation.Import;
26-
import org.springframework.integration.support.management.micrometer.MicrometerMetricsCaptorRegistrar;
26+
import org.springframework.integration.support.management.micrometer.MicrometerMetricsCaptorImportSelector;
2727

2828
/**
2929
* Enables default configuring of management in Spring Integration components in an existing application.
@@ -39,7 +39,7 @@
3939
@Target(ElementType.TYPE)
4040
@Retention(RetentionPolicy.RUNTIME)
4141
@Documented
42-
@Import({ MicrometerMetricsCaptorRegistrar.class, IntegrationManagementConfiguration.class })
42+
@Import({ MicrometerMetricsCaptorImportSelector.class, IntegrationManagementConfiguration.class })
4343
public @interface EnableIntegrationManagement {
4444

4545
/**

spring-integration-core/src/main/java/org/springframework/integration/graph/IntegrationGraphServer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
import org.springframework.integration.router.RecipientListRouterManagement;
4949
import org.springframework.integration.support.context.NamedComponent;
5050
import org.springframework.integration.support.management.MappingMessageRouterManagement;
51-
import org.springframework.integration.support.management.micrometer.MicrometerMetricsCaptorRegistrar;
51+
import org.springframework.integration.support.management.micrometer.MicrometerMetricsCaptorConfiguration;
5252
import org.springframework.integration.support.utils.IntegrationUtils;
5353
import org.springframework.lang.Nullable;
5454
import org.springframework.messaging.MessageChannel;
@@ -159,7 +159,7 @@ protected <T> Map<String, T> getBeansOfType(Class<T> type) {
159159
}
160160

161161
private synchronized Graph buildGraph() {
162-
if (micrometerEnhancer == null && MicrometerMetricsCaptorRegistrar.METER_REGISTRY_PRESENT) {
162+
if (micrometerEnhancer == null && MicrometerMetricsCaptorConfiguration.METER_REGISTRY_PRESENT) {
163163
micrometerEnhancer = new MicrometerNodeEnhancer(this.applicationContext);
164164
}
165165
String implementationVersion = IntegrationGraphServer.class.getPackage().getImplementationVersion();
Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@
1616

1717
package org.springframework.integration.support.management.micrometer;
1818

19-
import org.springframework.beans.factory.ListableBeanFactory;
20-
import org.springframework.beans.factory.config.BeanDefinition;
21-
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
22-
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
19+
import org.springframework.beans.factory.ObjectProvider;
20+
import org.springframework.context.annotation.Bean;
21+
import org.springframework.context.annotation.Configuration;
2322
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
24-
import org.springframework.core.type.AnnotationMetadata;
2523
import org.springframework.util.ClassUtils;
2624

2725
import io.micrometer.core.instrument.MeterRegistry;
@@ -35,7 +33,8 @@
3533
*
3634
* @since 5.2.9
3735
*/
38-
public class MicrometerMetricsCaptorRegistrar implements ImportBeanDefinitionRegistrar {
36+
@Configuration(proxyBeanMethods = false)
37+
public class MicrometerMetricsCaptorConfiguration {
3938

4039
/**
4140
* A {@code boolean} flag to indicate if the
@@ -45,18 +44,13 @@ public class MicrometerMetricsCaptorRegistrar implements ImportBeanDefinitionReg
4544
public static final boolean METER_REGISTRY_PRESENT =
4645
ClassUtils.isPresent("io.micrometer.core.instrument.MeterRegistry", null);
4746

48-
@Override
49-
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
50-
ListableBeanFactory beanFactory = (ListableBeanFactory) registry;
51-
if (METER_REGISTRY_PRESENT
52-
&& !registry.containsBeanDefinition(MicrometerMetricsCaptor.MICROMETER_CAPTOR_NAME)
53-
&& beanFactory.getBeanNamesForType(MeterRegistry.class, false, false).length > 0) {
54-
55-
registry.registerBeanDefinition(MicrometerMetricsCaptor.MICROMETER_CAPTOR_NAME,
56-
BeanDefinitionBuilder.genericBeanDefinition(MicrometerMetricsCaptor.class,
57-
() -> new MicrometerMetricsCaptor(beanFactory.getBeanProvider(MeterRegistry.class)))
58-
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE)
59-
.getBeanDefinition());
47+
@Bean(name = MicrometerMetricsCaptor.MICROMETER_CAPTOR_NAME)
48+
public MicrometerMetricsCaptor micrometerMetricsCaptor(ObjectProvider<MeterRegistry> meterRegistries) {
49+
if (meterRegistries.stream().findAny().isPresent()) {
50+
return new MicrometerMetricsCaptor(meterRegistries);
51+
}
52+
else {
53+
return null;
6054
}
6155
}
6256

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.integration.support.management.micrometer;
18+
19+
import org.springframework.context.annotation.ImportSelector;
20+
import org.springframework.core.type.AnnotationMetadata;
21+
22+
/**
23+
* An {@link ImportSelector} to conditionally add a {@link MicrometerMetricsCaptorConfiguration}
24+
* bean when {@code io.micrometer.core.instrument.MeterRegistry} is present in classpath.
25+
*
26+
* @author Artem Bilan
27+
*
28+
* @since 5.5.5
29+
*/
30+
public class MicrometerMetricsCaptorImportSelector implements ImportSelector {
31+
32+
@Override
33+
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
34+
if (MicrometerMetricsCaptorConfiguration.METER_REGISTRY_PRESENT) {
35+
return new String[]{ MicrometerMetricsCaptorConfiguration.class.getName() };
36+
}
37+
else {
38+
return new String[0];
39+
}
40+
}
41+
42+
}

0 commit comments

Comments
 (0)