简体   繁体   English

Spring 引导@Value 注释返回 null

[英]Spring boot @Value annotation returning null

I have a java class, shown below, that is creating a rest template with connection and read timeouts and also creates a retry template that is executing retries whenever a connection and read timeout occurs.我有一个 java class,如下所示,它正在创建一个带有连接和读取超时的 rest 模板,并且还会创建一个在发生连接和读取超时时执行重试的重试模板。 I am reading in the values from an application.properties file but for some reason I am getting null values for the values being read in. I have no idea what I can do to fix this.我正在从 application.properties 文件中读取值,但由于某种原因,我得到了正在读取的值的 null 值。我不知道我能做些什么来解决这个问题。 Any advice on this would be appreciated.对此的任何建议将不胜感激。

public class Retry {

@Value("${read.Timeout.InMilliSeconds:-1}")
private Integer readTimeoutInMilliSeconds;

@Value("${connect.Timeout.InMilliSeconds:-1}")
private Integer connectTimeoutInMilliSeconds;

@Value("${backOff.Period.InMilliSeconds:-1}")
private Integer backOffPeriodInMilliSeconds;

@Value("${max.Attempts:-1}")
private Integer maxAttempts;

@Bean
public RestTemplate restTemplate() {

    RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
    return restTemplate;
}

private HttpComponentsClientHttpRequestFactory getClientHttpRequestFactory() {

    HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
    requestFactory.setReadTimeout(readTimeoutInMilliSeconds);
    requestFactory.setConnectTimeout(connectTimeoutInMilliSeconds);
    return requestFactory;
}

@Bean
public RetryTemplate retryTemplate() {

    Map<Class<? extends Throwable>, Boolean> retryableExpressions = new HashMap<>();

    // connection and read timeouts
    retryableExpressions.put(ResourceAccessException.class, true);

    // 404
    retryableExpressions.put(RestClientException.class, false);

    SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy(maxAttempts, retryableExpressions);

    FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
    backOffPolicy.setBackOffPeriod(backOffPeriodInMilliSeconds);

    RetryTemplate retryTemplate = new RetryTemplate();
    retryTemplate.setRetryPolicy(simpleRetryPolicy);
    retryTemplate.setBackOffPolicy(backOffPolicy);

    return retryTemplate;
}

@Bean
public RetryRestTemplate retryRestTemplate() {
    return new RetryRestTemplate(
            restTemplate(),
            retryTemplate());
   }
}

application.properties应用程序属性

read.Timeout.InMilliSeconds=10000
connect.Timeout.InMilliSeconds=10000
backOff.PeriodInMilliSeconds=10000
max.Attempts=5

stack trace堆栈跟踪

Caused by: java.lang.NullPointerException: null
at com.beans.Retry.getClientHttpRequestFactory(Retry.java:43)
at com.beans.Retry.restTemplate(Retry.java:36)
at com.beans.Services.retryRestTemplate(Services.java:82)
at com.beans.Services$$EnhancerBySpringCGLIB$$819e8a9c.CGLIB$retryRestTemplate$3(<generated>)
at com.beans.Services$$EnhancerBySpringCGLIB$$819e8a9c$$FastClassBySpringCGLIB$$65931da6.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363)
at com.beans.Services$$EnhancerBySpringCGLIB$$819e8a9c.retryRestTemplate(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 213 common frames omitted

Process finished with exit code 1进程以退出代码 1 结束

RetryRestTemplate重试休息模板

public class RetryRestTemplate {

private RestTemplate restTemplate;
private RetryTemplate retryTemplate;

public RetryRestTemplate(RestTemplate restTemplate, RetryTemplate retryTemplate) {
    this.restTemplate = this.restTemplate;
    this.retryTemplate = this.retryTemplate;
}

public ResponseEntity getForEntity(URI uri, Class c) {
    return retryTemplate.execute(retryContext -> {
        System.out.println("Check");
        return restTemplate.getForEntity(uri, c);
    });
}

public ResponseEntity exchange(String url, HttpMethod get, HttpEntity headers, Class c) {
    return retryTemplate.execute(retryContext -> {
        return restTemplate.exchange(url, get, headers, c);
    });
}

public <T extends Object> ResponseEntity<T> postForEntity(String apiUrl, HttpEntity<Object> entityRequest, Class<T> responseClass) {
    return retryTemplate.execute(retryContext -> {
        return restTemplate.postForEntity(apiUrl, entityRequest, responseClass);
    });
}

} }

Class Retry maybe is not managed by Spring. Class Retry可能不受 Spring 管理。 Adding @Configuration upon Retry class.Retry class 时添加 @Configuration。

@Configuration
public class Retry {
}

Try to move @Value(...) into corresponging methods as input parameters as follows:尝试将@Value(...)作为输入参数移动到相应的方法中,如下所示:

private HttpComponentsClientHttpRequestFactory getClientHttpRequestFactory(
    @Value("${read.Timeout.InMilliSeconds:-1}") Integer readTimeoutInMilliSeconds,
    @Value("${connect.Timeout.InMilliSeconds:-1}") Integer connectTimeoutInMilliSeconds) {
    ...
}

@Bean
public RetryTemplate retryTemplate(
    @Value("${backOff.Period.InMilliSeconds:-1}") Integer backOffPeriodInMilliSeconds,
    @Value("${max.Attempts:-1}") Integer maxAttempts) {
    ...
}

Or you can also try to create a constructor for Retry and use @Value for constructor arguments:或者您也可以尝试为Retry创建一个构造函数,并将@Value用于构造函数 arguments:

private Integer readTimeoutInMilliSeconds;
private Integer connectTimeoutInMilliSeconds;
private Integer backOffPeriodInMilliSeconds;
private Integer maxAttempts;

Retry(@Value("${read.Timeout.InMilliSeconds:-1}") Integer readTimeoutInMilliSeconds,
      @Value("${connect.Timeout.InMilliSeconds:-1}") Integer connectTimeoutInMilliSeconds,
      @Value("${backOff.Period.InMilliSeconds:-1}") Integer backOffPeriodInMilliSeconds,
      @Value("${max.Attempts:-1}") Integer maxAttempts) {
    this.readTimeoutInMilliSeconds = readTimeoutInMilliSeconds;
    this.connectTimeoutInMilliSeconds = connectTimeoutInMilliSeconds;
    this.backOffPeriodInMilliSeconds = backOffPeriodInMilliSeconds;
    this.maxAttempts = maxAttempts;
}

Apart from @Value annotation, there is other way to get properties value.除了@Value注解之外,还有其他方法可以获取属性值。 By using the Environment Interface's instance.通过使用Environment接口的实例。

Follow the below steps:请按照以下步骤操作:

  1. Add @Component annotation on Retry.javaRetry.java上添加@Component注释
  2. Import and Autowired Environment in your Retry.java Retry.java中的导入和自动装配Environment

     import org.springframework.core.env.Environment @Autowired private Environment env;
  3. Get value of the property from env.从 env 获取属性的值。 For example,例如,

    env.getProperty("read.Timeout.InMilliSeconds","-1");

There are several other flavors also to the value of the property.该物业的价值还有其他几种口味。 You can check it out on this .你可以看看这个

2 Things: 2件事:
1) As others said add configuration 1)正如其他人所说,添加配置
2)Check if you're using Retry as Autowired in any class for which object is created. 2)检查您是否在为其创建 object 的任何 class 中使用 Retry as Autowired。 If any bean class is used in an instantiated object, it returns null.如果在实例化的 object 中使用任何 bean class,它将返回 null。

Please add the following annotations in your Retry.java请在您的Retry.java中添加以下注释

@Configuration
@PropertySource("classpath:application.properties")

and change your @Value annotations like below并更改您的@Value注释,如下所示

@Value("#{'${read.Timeout.InMilliSeconds:-1}'}")
private Integer readTimeoutInMilliSeconds;

And it should work!它应该工作!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM