From e7f31ae334cb061ff4a35dc4fd6a67c22bec0e17 Mon Sep 17 00:00:00 2001 From: Chris Bono Date: Sun, 5 May 2024 11:31:02 -0500 Subject: [PATCH] Make bean customizer static to appease AOT (#671) --- .../pulsar/annotation/BeanCustomizer.java | 34 ---------- ...erFactoryBeanCustomizerPostProcessor.java} | 32 ++++----- .../PulsarBootstrapConfiguration.java | 28 ++------ ...arTemplateBeanCustomizerPostProcessor.java | 66 +++++++++++++++++++ ...sarListenerContainerFactoryCustomizer.java | 12 ++-- .../pulsar/core/PulsarTemplateCustomizer.java | 11 +++- 6 files changed, 99 insertions(+), 84 deletions(-) delete mode 100644 spring-pulsar/src/main/java/org/springframework/pulsar/annotation/BeanCustomizer.java rename spring-pulsar/src/main/java/org/springframework/pulsar/annotation/{BeanCustomizerPostProcessor.java => ConcurrentPulsarListenerContainerFactoryBeanCustomizerPostProcessor.java} (67%) create mode 100644 spring-pulsar/src/main/java/org/springframework/pulsar/annotation/PulsarTemplateBeanCustomizerPostProcessor.java diff --git a/spring-pulsar/src/main/java/org/springframework/pulsar/annotation/BeanCustomizer.java b/spring-pulsar/src/main/java/org/springframework/pulsar/annotation/BeanCustomizer.java deleted file mode 100644 index 24cb7b3a..00000000 --- a/spring-pulsar/src/main/java/org/springframework/pulsar/annotation/BeanCustomizer.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2023-2024 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.pulsar.annotation; - -/** - * Customize a bean. - * - * @param the bean type to customize - * @author Chris Bono - */ -@FunctionalInterface -public interface BeanCustomizer { - - /** - * Customize the bean. - * @param bean the bean to customize - */ - void customize(B bean); - -} diff --git a/spring-pulsar/src/main/java/org/springframework/pulsar/annotation/BeanCustomizerPostProcessor.java b/spring-pulsar/src/main/java/org/springframework/pulsar/annotation/ConcurrentPulsarListenerContainerFactoryBeanCustomizerPostProcessor.java similarity index 67% rename from spring-pulsar/src/main/java/org/springframework/pulsar/annotation/BeanCustomizerPostProcessor.java rename to spring-pulsar/src/main/java/org/springframework/pulsar/annotation/ConcurrentPulsarListenerContainerFactoryBeanCustomizerPostProcessor.java index 69342f5d..73041a51 100644 --- a/spring-pulsar/src/main/java/org/springframework/pulsar/annotation/BeanCustomizerPostProcessor.java +++ b/spring-pulsar/src/main/java/org/springframework/pulsar/annotation/ConcurrentPulsarListenerContainerFactoryBeanCustomizerPostProcessor.java @@ -21,53 +21,47 @@ import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.log.LogAccessor; +import org.springframework.pulsar.config.ConcurrentPulsarListenerContainerFactory; +import org.springframework.pulsar.config.ConcurrentPulsarListenerContainerFactoryCustomizer; import org.springframework.util.CollectionUtils; /** - * A {@link BeanPostProcessor} that applies a customizer to beans of a specified type. + * Applies a {@link ConcurrentPulsarListenerContainerFactoryCustomizer} to all + * {@link ConcurrentPulsarListenerContainerFactory} beans. *

* There must be only one customizer in the application context in order for it to be * applied. * - * @param the type of bean to customize - * @param the type of customizer * @author Chris Bono */ -class BeanCustomizerPostProcessor> +class ConcurrentPulsarListenerContainerFactoryBeanCustomizerPostProcessor implements BeanPostProcessor, ApplicationContextAware { private final LogAccessor logger = new LogAccessor(getClass()); - private final Class beanType; - - private final Class customizerType; - private ApplicationContext applicationContext; - BeanCustomizerPostProcessor(Class beanType, Class customizerType) { - this.beanType = beanType; - this.customizerType = customizerType; - } - @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } + @SuppressWarnings("unchecked") @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - if (this.beanType.isInstance(bean)) { - B typedBean = this.beanType.cast(bean); - var customizers = this.applicationContext.getBeansOfType(this.customizerType); + if (bean instanceof ConcurrentPulsarListenerContainerFactory containerFactory) { + var customizers = this.applicationContext + .getBeansOfType(ConcurrentPulsarListenerContainerFactoryCustomizer.class); if (CollectionUtils.isEmpty(customizers)) { return bean; } if (customizers.size() > 1) { - this.logger.warn("Found multiple %s beans [%s] - must be only 1 in order to apply" - .formatted(this.customizerType.getSimpleName(), customizers.keySet())); + this.logger.warn("Found multiple %s beans [%s] - must be only 1 in order to apply".formatted( + ConcurrentPulsarListenerContainerFactoryCustomizer.class.getSimpleName(), + customizers.keySet())); } else { - customizers.values().stream().forEach((c) -> c.customize(typedBean)); + customizers.values().forEach((c) -> c.customize(containerFactory)); } } return bean; diff --git a/spring-pulsar/src/main/java/org/springframework/pulsar/annotation/PulsarBootstrapConfiguration.java b/spring-pulsar/src/main/java/org/springframework/pulsar/annotation/PulsarBootstrapConfiguration.java index 02553918..e8aa4c7e 100644 --- a/spring-pulsar/src/main/java/org/springframework/pulsar/annotation/PulsarBootstrapConfiguration.java +++ b/spring-pulsar/src/main/java/org/springframework/pulsar/annotation/PulsarBootstrapConfiguration.java @@ -16,19 +16,13 @@ package org.springframework.pulsar.annotation; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; -import org.springframework.core.ResolvableType; import org.springframework.core.type.AnnotationMetadata; -import org.springframework.pulsar.config.ConcurrentPulsarListenerContainerFactory; -import org.springframework.pulsar.config.ConcurrentPulsarListenerContainerFactoryCustomizer; import org.springframework.pulsar.config.PulsarAnnotationSupportBeanNames; import org.springframework.pulsar.config.PulsarListenerEndpointRegistry; import org.springframework.pulsar.config.PulsarReaderEndpointRegistry; -import org.springframework.pulsar.core.PulsarTemplate; -import org.springframework.pulsar.core.PulsarTemplateCustomizer; /** * An {@link ImportBeanDefinitionRegistrar} class that registers a @@ -51,27 +45,13 @@ public class PulsarBootstrapConfiguration implements ImportBeanDefinitionRegistr @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { if (!registry.containsBeanDefinition("pulsarTemplateCustomizerPostProcessor")) { - var postProcessorType = ResolvableType.forClassWithGenerics(BeanCustomizerPostProcessor.class, - PulsarTemplate.class, PulsarTemplateCustomizer.class); - @SuppressWarnings("unchecked") - var beanDef = BeanDefinitionBuilder - .rootBeanDefinition(postProcessorType, - () -> new BeanCustomizerPostProcessor<>(PulsarTemplate.class, PulsarTemplateCustomizer.class)) - .getBeanDefinition(); - registry.registerBeanDefinition("pulsarTemplateCustomizerPostProcessor", beanDef); + registry.registerBeanDefinition("pulsarTemplateCustomizerPostProcessor", + new RootBeanDefinition(PulsarTemplateBeanCustomizerPostProcessor.class)); } if (!registry.containsBeanDefinition("concurrentContainerFactoryCustomizerPostProcessor")) { - var postProcessorType = ResolvableType.forClassWithGenerics(BeanCustomizerPostProcessor.class, - ConcurrentPulsarListenerContainerFactory.class, - ConcurrentPulsarListenerContainerFactoryCustomizer.class); - @SuppressWarnings("unchecked") - var beanDef = BeanDefinitionBuilder - .rootBeanDefinition(postProcessorType, - () -> new BeanCustomizerPostProcessor<>(ConcurrentPulsarListenerContainerFactory.class, - ConcurrentPulsarListenerContainerFactoryCustomizer.class)) - .getBeanDefinition(); - registry.registerBeanDefinition("concurrentContainerFactoryCustomizerPostProcessor", beanDef); + registry.registerBeanDefinition("concurrentContainerFactoryCustomizerPostProcessor", + new RootBeanDefinition(ConcurrentPulsarListenerContainerFactoryBeanCustomizerPostProcessor.class)); } if (!registry diff --git a/spring-pulsar/src/main/java/org/springframework/pulsar/annotation/PulsarTemplateBeanCustomizerPostProcessor.java b/spring-pulsar/src/main/java/org/springframework/pulsar/annotation/PulsarTemplateBeanCustomizerPostProcessor.java new file mode 100644 index 00000000..3f131800 --- /dev/null +++ b/spring-pulsar/src/main/java/org/springframework/pulsar/annotation/PulsarTemplateBeanCustomizerPostProcessor.java @@ -0,0 +1,66 @@ +/* + * Copyright 2023-2024 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.pulsar.annotation; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.core.log.LogAccessor; +import org.springframework.pulsar.core.PulsarTemplate; +import org.springframework.pulsar.core.PulsarTemplateCustomizer; +import org.springframework.util.CollectionUtils; + +/** + * Applies a {@link PulsarTemplateCustomizer} to all {@link PulsarTemplate} beans. + *

+ * There must be only one customizer in the application context in order for it to be + * applied. + * + * @author Chris Bono + */ +class PulsarTemplateBeanCustomizerPostProcessor implements BeanPostProcessor, ApplicationContextAware { + + private final LogAccessor logger = new LogAccessor(getClass()); + + private ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + @SuppressWarnings("unchecked") + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof PulsarTemplate template) { + var customizers = this.applicationContext.getBeansOfType(PulsarTemplateCustomizer.class); + if (CollectionUtils.isEmpty(customizers)) { + return bean; + } + if (customizers.size() > 1) { + this.logger.warn("Found multiple %s beans [%s] - must be only 1 in order to apply" + .formatted(PulsarTemplateCustomizer.class.getSimpleName(), customizers.keySet())); + } + else { + customizers.values().stream().forEach((c) -> c.customize(template)); + } + } + return bean; + } + +} diff --git a/spring-pulsar/src/main/java/org/springframework/pulsar/config/ConcurrentPulsarListenerContainerFactoryCustomizer.java b/spring-pulsar/src/main/java/org/springframework/pulsar/config/ConcurrentPulsarListenerContainerFactoryCustomizer.java index 420c7cf4..3c389076 100644 --- a/spring-pulsar/src/main/java/org/springframework/pulsar/config/ConcurrentPulsarListenerContainerFactoryCustomizer.java +++ b/spring-pulsar/src/main/java/org/springframework/pulsar/config/ConcurrentPulsarListenerContainerFactoryCustomizer.java @@ -16,8 +16,6 @@ package org.springframework.pulsar.config; -import org.springframework.pulsar.annotation.BeanCustomizer; - /** * Callback interface that can be implemented to customize a * {@link ConcurrentPulsarListenerContainerFactory}. @@ -25,7 +23,13 @@ import org.springframework.pulsar.annotation.BeanCustomizer; * @param The message payload type * @author Chris Bono */ -public interface ConcurrentPulsarListenerContainerFactoryCustomizer - extends BeanCustomizer> { +@FunctionalInterface +public interface ConcurrentPulsarListenerContainerFactoryCustomizer { + + /** + * Customize a {@link ConcurrentPulsarListenerContainerFactory}. + * @param containerFactory the factory to customize + */ + void customize(ConcurrentPulsarListenerContainerFactory containerFactory); } diff --git a/spring-pulsar/src/main/java/org/springframework/pulsar/core/PulsarTemplateCustomizer.java b/spring-pulsar/src/main/java/org/springframework/pulsar/core/PulsarTemplateCustomizer.java index ab75f47f..b7ee5f64 100644 --- a/spring-pulsar/src/main/java/org/springframework/pulsar/core/PulsarTemplateCustomizer.java +++ b/spring-pulsar/src/main/java/org/springframework/pulsar/core/PulsarTemplateCustomizer.java @@ -16,14 +16,19 @@ package org.springframework.pulsar.core; -import org.springframework.pulsar.annotation.BeanCustomizer; - /** * Callback interface that can be implemented to customize a {@link PulsarTemplate}. * * @param the payload type of the template * @author Chris Bono */ -public interface PulsarTemplateCustomizer extends BeanCustomizer> { +@FunctionalInterface +public interface PulsarTemplateCustomizer { + + /** + * Customize a {@link PulsarTemplate}. + * @param template the template to customize + */ + void customize(PulsarTemplate template); }