【发布时间】:2021-02-22 11:51:22
【问题描述】:
我正在将 Spring 与 Spring Boot BOM 2.4.0 附带的遗留 Tomcat 应用程序(不是 Spring Boot)一起使用,问题类似于 Spring Expression Language not working,但我有一个具体案例。
如果我有一个 @Value("${spring.kafka.maximumRequestSize:15728640}") 和以下的依赖类
@Configuration
@Order
public class KafkaTracingDecorator implements ApplicationContextAware {
private KafkaTracing kafkaTracing;
@Override
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
kafkaTracing = applicationContext.getBean(KafkaTracing.class);
}
}
它有效。以下也有效,但我没有在后处理器上做任何事情
@Configuration
@Order
public class KafkaTracingDecorator implements BeanPostProcessor, ApplicationContextAware {
@Override
public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException {
return bean;
}
@Override
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
// kafkaTracing = applicationContext.getBean(KafkaTracing.class);
}
}
但是当我尝试像这样实现BeanPostProcessor 到implement the decorator pattern 时
@Configuration
@Order
public class KafkaTracingDecorator implements BeanPostProcessor, ApplicationContextAware {
private KafkaTracing kafkaTracing;
@Override
public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException {
if (bean instanceof KafkaProducer) {
return kafkaTracing.producer((KafkaProducer) bean);
} else if (bean instanceof KafkaConsumer) {
return kafkaTracing.consumer((KafkaConsumer) bean);
} else {
return bean;
}
}
@Override
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
kafkaTracing = applicationContext.getBean(KafkaTracing.class);
}
}
在创建 WebApplicationContext 时我得到Caused by: java.lang.NumberFormatException: For input string: "${spring.kafka.maximumRequestSize:15728640}"。
即使我不使用该值也会发生这种情况,因此它不会进入方法
@Configuration
@Order
public class KafkaTracingDecorator implements BeanPostProcessor, ApplicationContextAware {
private KafkaTracing kafkaTracing;
@Override
public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException {
return bean;
}
@Override
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
kafkaTracing = applicationContext.getBean(KafkaTracing.class);
}
}
这是一个非常简化的示例,但也以同样的方式失败:
@Configuration
public class KafkaTracingDecorator implements BeanPostProcessor {
@Value("${spring.kafka.maximumRequestSize:15728640}")
private int maxRequestSize;
}
(请注意,这在 Spring Boot 上按预期工作,因此可能与 Spring 的非引导使用有关)
导致错误的部分堆栈跟踪未列出任何自定义代码:
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:660)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1413)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213)
at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:270)
at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:761)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:566)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:401)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:292)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4689)
MVCE 添加:https://github.com/trajano/spring-beanpostproc-mvce 链接到 GitHub 问题,以防这是一个错误 https://github.com/spring-projects/spring-framework/issues/26571,而不是使用问题。
【问题讨论】:
-
在构建 WebApplicationContext 时启动。更新了 Q 以包含该事实
-
不能这样做,它不是一个开源项目,我正在尝试创建一个显示它的 MVCE,但它在 MVCE 本身中工作。
-
谢谢,我基本上是在将 Spring Boot 启动器调整为 Tomcat + WAR 部署,希望问题会显现出来。
-
我注意到它已经在 Spring Boot 上运行了。我确实添加了现在证明失败的 MVCE。在 Dockerized 的 tomcat 上。
-
@AnishB。你有答案吗?