Make bean customizer static to appease AOT (#671)
This commit is contained in:
@@ -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 <B> the bean type to customize
|
||||
* @author Chris Bono
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface BeanCustomizer<B> {
|
||||
|
||||
/**
|
||||
* Customize the bean.
|
||||
* @param bean the bean to customize
|
||||
*/
|
||||
void customize(B bean);
|
||||
|
||||
}
|
||||
@@ -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.
|
||||
* <p>
|
||||
* There must be only one customizer in the application context in order for it to be
|
||||
* applied.
|
||||
*
|
||||
* @param <B> the type of bean to customize
|
||||
* @param <C> the type of customizer
|
||||
* @author Chris Bono
|
||||
*/
|
||||
class BeanCustomizerPostProcessor<B, C extends BeanCustomizer<B>>
|
||||
class ConcurrentPulsarListenerContainerFactoryBeanCustomizerPostProcessor
|
||||
implements BeanPostProcessor, ApplicationContextAware {
|
||||
|
||||
private final LogAccessor logger = new LogAccessor(getClass());
|
||||
|
||||
private final Class<B> beanType;
|
||||
|
||||
private final Class<C> customizerType;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
BeanCustomizerPostProcessor(Class<B> beanType, Class<C> 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;
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
* <p>
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 <T> The message payload type
|
||||
* @author Chris Bono
|
||||
*/
|
||||
public interface ConcurrentPulsarListenerContainerFactoryCustomizer<T>
|
||||
extends BeanCustomizer<ConcurrentPulsarListenerContainerFactory<T>> {
|
||||
@FunctionalInterface
|
||||
public interface ConcurrentPulsarListenerContainerFactoryCustomizer<T> {
|
||||
|
||||
/**
|
||||
* Customize a {@link ConcurrentPulsarListenerContainerFactory}.
|
||||
* @param containerFactory the factory to customize
|
||||
*/
|
||||
void customize(ConcurrentPulsarListenerContainerFactory<T> containerFactory);
|
||||
|
||||
}
|
||||
|
||||
@@ -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 <T> the payload type of the template
|
||||
* @author Chris Bono
|
||||
*/
|
||||
public interface PulsarTemplateCustomizer<T> extends BeanCustomizer<PulsarTemplate<T>> {
|
||||
@FunctionalInterface
|
||||
public interface PulsarTemplateCustomizer<T> {
|
||||
|
||||
/**
|
||||
* Customize a {@link PulsarTemplate}.
|
||||
* @param template the template to customize
|
||||
*/
|
||||
void customize(PulsarTemplate<T> template);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user