Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法从BeanPostProcessor中的占位符获取值_Java_Spring - Fatal编程技术网

Java 无法从BeanPostProcessor中的占位符获取值

Java 无法从BeanPostProcessor中的占位符获取值,java,spring,Java,Spring,我将Spring与Spring Boot BOM 2.4.0附带的遗留Tomcat应用程序(不是Spring Boot)一起使用,问题与之类似,但我有一个特定的案例 如果我有一个具有@Value(${spring.kafka.maximumRequestSize:15728640})的依赖类和以下内容 @Configuration @Order public class KafkaTracingDecorator implements ApplicationContextAware {

我将Spring与Spring Boot BOM 2.4.0附带的遗留Tomcat应用程序(不是Spring Boot)一起使用,问题与之类似,但我有一个特定的案例

如果我有一个具有
@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

@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时,我得到由以下原因引起的
:java.lang.NumberFormatException:For输入字符串:“${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引导的预期效果相同,因此可能与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添加:链接到GitHub问题,以防它是一个bug而不是使用问题。

您需要通过注册
PropertySourcesPlaceholderConfigurer
bean来更新
Decorator
类,以解决您的问题

根据:

PropertyPlaceHolderConfiguration占位符配置支持的子类。此子类有助于根据本地属性和/或系统属性和环境变量解析占位符

因此,配置此bean将从类路径加载应用程序.properties,它将能够解析
${..}
注释中使用的
@Value
以获得实际值集

更新的装饰器类:

@Configuration
public class Decorator implements BeanPostProcessor {
    
    @Value("${spring.kafka.maximumRequestSize}")
    private int maxRequestSize;
    
    @Bean
    public static PlaceholderConfigurerSupport placeholderConfigurerSupport() {
        PlaceholderConfigurerSupport support = new PropertySourcesPlaceholderConfigurer();
        support.setLocations(new ClassPathResource("application.properties"));
        return support;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(maxRequestSize);
        return bean;
    }
}
应用程序属性

spring.kafka.maximumRequestSize=15728640
...
.....
INFO: Initializing Spring root WebApplicationContext
Feb 20, 2021 9:21:41 AM org.springframework.web.context.ContextLoader initWebApplicationContext
INFO: Root WebApplicationContext: initialization started
15728640
Feb 20, 2021 9:21:41 AM org.springframework.web.context.ContextLoader initWebApplicationContext
INFO: Root WebApplicationContext initialized in 518 ms
Feb 20, 2021 9:21:41 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8080"]
Feb 20, 2021 9:21:41 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 1419 ms
运行在采用的OpenJDK 11.0.6上的Tomcat 8.5.57的控制台日志:

spring.kafka.maximumRequestSize=15728640
...
.....
INFO: Initializing Spring root WebApplicationContext
Feb 20, 2021 9:21:41 AM org.springframework.web.context.ContextLoader initWebApplicationContext
INFO: Root WebApplicationContext: initialization started
15728640
Feb 20, 2021 9:21:41 AM org.springframework.web.context.ContextLoader initWebApplicationContext
INFO: Root WebApplicationContext initialized in 518 ms
Feb 20, 2021 9:21:41 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8080"]
Feb 20, 2021 9:21:41 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 1419 ms

在构建WebApplicationContext时启动。更新了Q以包含factCan不能做到这一点,它不是一个开源项目,我正在尝试创建一个MVCE来显示它,但它在MVCE本身工作。Thx我基本上调整了Spring Boot starter,使之成为Tomcat+WAR部署,希望问题会显现出来。我注意到它已经在Spring Boot上工作了。我确实添加了MVCE,现在证明了失败。在一只停靠的雄猫身上。你有答案吗?是的,MVCE会处理这个更改,并在更大的项目上尝试。我想问另一个问题,但是你可以使用哪种资源让“环境变量”设置属性。这个问题的第二部分,支持bean需要在这个配置中定义,还是可以在外部定义?我刚刚测试过,它可以是外部的,将它分开可能是一个更好的答案,而不是嵌入到decorator中。所以我注意到您使用的是静态的,我在MVCE上测试过,它看起来不需要static@ArchimedesTrajano是 啊但如果没有静电干扰,数据就不会被采集。我的情况是零。它是否从您的案例中的属性中获取了正确的价值?