Skip to content

GH-3502: Make the framework compatible with Native #3531

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
package org.springframework.integration.config;

import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.springframework.beans.BeansException;
Expand Down Expand Up @@ -130,39 +128,18 @@ public void afterSingletonsInstantiated() {
Assert.state(this.applicationContext != null, "'applicationContext' must not be null");
Assert.state(MANAGEMENT_CONFIGURER_NAME.equals(this.beanName), getClass().getSimpleName()
+ " bean name must be " + MANAGEMENT_CONFIGURER_NAME);

if (obtainMetricsCaptor() != null) {
injectCaptor();
registerComponentGauges();
}
Map<String, IntegrationManagement> managed = this.applicationContext
.getBeansOfType(IntegrationManagement.class);
for (Entry<String, IntegrationManagement> entry : managed.entrySet()) {
IntegrationManagement bean = entry.getValue();
if (!getOverrides(bean).loggingConfigured) {
bean.setLoggingEnabled(this.defaultLoggingEnabled);
}
}
this.singletonsInstantiated = true;
}

private void injectCaptor() {
Map<String, IntegrationManagement> managed =
this.applicationContext.getBeansOfType(IntegrationManagement.class);
for (Entry<String, IntegrationManagement> entry : managed.entrySet()) {
IntegrationManagement bean = entry.getValue();
if (!getOverrides(bean).loggingConfigured) {
bean.setLoggingEnabled(this.defaultLoggingEnabled);
}
bean.registerMetricsCaptor(this.metricsCaptor);
}
}
for (IntegrationManagement integrationManagement :
this.applicationContext.getBeansOfType(IntegrationManagement.class).values()) {

@Override
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
if (this.singletonsInstantiated && obtainMetricsCaptor() != null && bean instanceof IntegrationManagement) {
((IntegrationManagement) bean).registerMetricsCaptor(this.metricsCaptor);
enhanceIntegrationManagement(integrationManagement);
}
return bean;

this.singletonsInstantiated = true;
}

private void registerComponentGauges() {
Expand All @@ -185,6 +162,23 @@ private void registerComponentGauges() {
.build());
}

private void enhanceIntegrationManagement(IntegrationManagement integrationManagement) {
if (!getOverrides(integrationManagement).loggingConfigured) {
integrationManagement.setLoggingEnabled(this.defaultLoggingEnabled);
}
if (this.metricsCaptor != null) {
integrationManagement.registerMetricsCaptor(this.metricsCaptor);
}
}

@Override
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
if (this.singletonsInstantiated && bean instanceof IntegrationManagement) {
enhanceIntegrationManagement((IntegrationManagement) bean);
}
return bean;
}

@Override public void onApplicationEvent(ContextClosedEvent event) {
if (event.getApplicationContext().equals(this.applicationContext)) {
this.gauges.forEach(MeterFacade::remove);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2021 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.
Expand All @@ -24,6 +24,7 @@
import org.springframework.beans.factory.support.ManagedSet;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.NativeDetector;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.integration.config.annotation.MessagingAnnotationPostProcessor;
import org.springframework.integration.context.IntegrationContextUtils;
Expand All @@ -46,7 +47,7 @@ public class IntegrationRegistrar implements ImportBeanDefinitionRegistrar {
IntegrationRegistrar.class.getClassLoader())) {

throw new ApplicationContextException("Starting with Spring Integration 5.0, "
+ "the 'spring-integration-java-dsl' dependency is no longer needed; "
+ "the 'spring-integration-java-dsl' dependency is no longer needed; "
+ "the Java DSL has been merged into the core project. "
+ "If it is present on the classpath, it will cause class loading conflicts.");
}
Expand Down Expand Up @@ -108,7 +109,8 @@ private void registerImplicitChannelCreator(BeanDefinitionRegistry registry) {
private void registerDefaultConfiguringBeanFactoryPostProcessor(BeanDefinitionRegistry registry) {
if (!registry.containsBeanDefinition(IntegrationContextUtils.DEFAULT_CONFIGURING_POSTPROCESSOR_BEAN_NAME)) {
BeanDefinitionBuilder postProcessorBuilder =
BeanDefinitionBuilder.genericBeanDefinition(DefaultConfiguringBeanFactoryPostProcessor.class);
BeanDefinitionBuilder.genericBeanDefinition(DefaultConfiguringBeanFactoryPostProcessor.class,
DefaultConfiguringBeanFactoryPostProcessor::new);
BeanDefinitionHolder postProcessorHolder = new BeanDefinitionHolder(
postProcessorBuilder.getBeanDefinition(),
IntegrationContextUtils.DEFAULT_CONFIGURING_POSTPROCESSOR_BEAN_NAME);
Expand All @@ -121,7 +123,8 @@ private void registerDefaultConfiguringBeanFactoryPostProcessor(BeanDefinitionRe
* to process the external Integration infrastructure.
*/
private void registerIntegrationConfigurationBeanFactoryPostProcessor(BeanDefinitionRegistry registry) {
if (!registry.containsBeanDefinition(
if (!(NativeDetector.inNativeImage()) // Spring Native detects all the 'spring.factories'
&& !registry.containsBeanDefinition(
IntegrationContextUtils.INTEGRATION_CONFIGURATION_POST_PROCESSOR_BEAN_NAME)) {

BeanDefinitionBuilder postProcessorBuilder = BeanDefinitionBuilder
Expand All @@ -143,7 +146,8 @@ private void registerIntegrationConfigurationBeanFactoryPostProcessor(BeanDefini
private void registerMessagingAnnotationPostProcessors(AnnotationMetadata meta, BeanDefinitionRegistry registry) {
if (!registry.containsBeanDefinition(IntegrationContextUtils.MESSAGING_ANNOTATION_POSTPROCESSOR_NAME)) {
BeanDefinitionBuilder builder =
BeanDefinitionBuilder.genericBeanDefinition(MessagingAnnotationPostProcessor.class)
BeanDefinitionBuilder.genericBeanDefinition(MessagingAnnotationPostProcessor.class,
MessagingAnnotationPostProcessor::new)
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

registry.registerBeanDefinition(IntegrationContextUtils.MESSAGING_ANNOTATION_POSTPROCESSOR_NAME,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public abstract class IntegrationContextUtils {
IntegrationConfigUtils.BASE_PACKAGE + ".internalPublisherAnnotationBeanPostProcessor";

public static final String INTEGRATION_CONFIGURATION_POST_PROCESSOR_BEAN_NAME =
"IntegrationConfigurationBeanFactoryPostProcessor";
"integrationConfigurationBeanFactoryPostProcessor";

public static final String INTEGRATION_MESSAGE_HISTORY_CONFIGURER_BEAN_NAME = "messageHistoryConfigurer";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2021 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.
Expand Down Expand Up @@ -36,7 +36,7 @@
*
* @since 5.0
*
* @see org.springframework.messaging.handler.annotation.support.PayloadArgumentResolver
* @see org.springframework.messaging.handler.annotation.support.PayloadMethodArgumentResolver
*/
public class PayloadExpressionArgumentResolver extends AbstractExpressionEvaluator
implements HandlerMethodArgumentResolver {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2021 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.
Expand All @@ -18,6 +18,7 @@

import java.util.Arrays;

import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;

/**
Expand All @@ -39,7 +40,7 @@ public class DefaultMessageBuilderFactory implements MessageBuilderFactory {
* and {@link org.springframework.messaging.MessageHeaders#TIMESTAMP}.
* @since 4.3.2
*/
public void setReadOnlyHeaders(String... readOnlyHeaders) {
public void setReadOnlyHeaders(@Nullable String... readOnlyHeaders) {
this.readOnlyHeaders = readOnlyHeaders != null ? Arrays.copyOf(readOnlyHeaders, readOnlyHeaders.length) : null;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2015-2020 the original author or authors.
* Copyright 2015-2021 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.
Expand Down Expand Up @@ -69,6 +69,14 @@ public class SmartLifecycleRoleController implements ApplicationListener<Abstrac

private ApplicationContext applicationContext;

/**
* Construct an instance without any lifecycle initially: can be added later on via
* {@link #addLifecycleToRole(String, SmartLifecycle)}.
* @since 5.5
*/
public SmartLifecycleRoleController() {
}

/**
* Construct an instance with the provided lists of roles and lifecycles, which must be of equal length.
* @param roles the roles.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.ClassUtils;

import io.micrometer.core.instrument.MeterRegistry;

/**
* An {@link ImportBeanDefinitionRegistrar} to conditionally add a {@link MicrometerMetricsCaptor}
* bean when {@code io.micrometer.core.instrument.MeterRegistry} is present in classpath and
Expand All @@ -35,30 +37,19 @@
*/
public class MicrometerMetricsCaptorRegistrar implements ImportBeanDefinitionRegistrar {

private static final Class<?> METER_REGISTRY_CLASS;

static {
Class<?> aClass = null;
try {
aClass = ClassUtils.forName("io.micrometer.core.instrument.MeterRegistry",
ClassUtils.getDefaultClassLoader());
}
catch (ClassNotFoundException e) {
// Ignore - no Micrometer in classpath
}
METER_REGISTRY_CLASS = aClass;
}
private static final boolean METER_REGISTRY_PRESENT
= ClassUtils.isPresent("io.micrometer.core.instrument.MeterRegistry", ClassUtils.getDefaultClassLoader());

@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
ListableBeanFactory beanFactory = (ListableBeanFactory) registry;
if (METER_REGISTRY_CLASS != null
if (METER_REGISTRY_PRESENT
&& !registry.containsBeanDefinition(MicrometerMetricsCaptor.MICROMETER_CAPTOR_NAME)
&& beanFactory.getBeanNamesForType(METER_REGISTRY_CLASS, false, false).length > 0) {
&& beanFactory.getBeanNamesForType(MeterRegistry.class, false, false).length > 0) {

registry.registerBeanDefinition(MicrometerMetricsCaptor.MICROMETER_CAPTOR_NAME,
BeanDefinitionBuilder.genericBeanDefinition(MicrometerMetricsCaptor.class)
.addConstructorArgValue(beanFactory.getBeanProvider(METER_REGISTRY_CLASS))
BeanDefinitionBuilder.genericBeanDefinition(MicrometerMetricsCaptor.class,
() -> new MicrometerMetricsCaptor(beanFactory.getBeanProvider(MeterRegistry.class)))
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE)
.getBeanDefinition());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2019 the original author or authors.
* Copyright 2016-2021 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.
Expand Down Expand Up @@ -40,7 +40,7 @@
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Import(IntegrationGraphControllerRegistrarImportSelector.class)
@Import(IntegrationGraphControllerRegistrar.class)
public @interface EnableIntegrationGraphController {

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2019 the original author or authors.
* Copyright 2016-2021 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.
Expand Down Expand Up @@ -28,6 +28,7 @@

/**
* The {@link BeanDefinitionParser} for the {@code <int-http:graph-controller>} component.
*
* @author Artem Bilan
*
* @since 4.3
Expand All @@ -39,22 +40,15 @@ public class IntegrationGraphControllerParser implements BeanDefinitionParser {

@Override
public BeanDefinition parse(final Element element, ParserContext parserContext) {
if (HttpContextUtils.WEB_MVC_PRESENT) {
this.graphControllerRegistrar.registerBeanDefinitions(
new AnnotationMetadataAdapter() {

@Override
public Map<String, Object> getAnnotationAttributes(String annotationType) {
return Collections.singletonMap("value", element.getAttribute("path"));
}

}, parserContext.getRegistry());
}
else {
parserContext.getReaderContext().warning("The 'IntegrationGraphController' isn't registered " +
"with the application context because" +
" there is no 'org.springframework.web.servlet.DispatcherServlet' in the classpath.", element);
}
this.graphControllerRegistrar.registerBeanDefinitions(
new AnnotationMetadataAdapter() {

@Override
public Map<String, Object> getAnnotationAttributes(String annotationType) {
return Collections.singletonMap("value", element.getAttribute("path"));
}

}, parserContext.getRegistry());

return null;
}
Expand Down
Loading