2

我编写了一个 ClientHttpRequestInterceptor 实现来自动将一些 HttpHeaders 插入到我的 Spring Boot 服务的任何传出请求中。

我要支持的标头之一是指示发送此请求的源应用程序。为此,我将“spring.application.name”应用程序属性注入到一个私有变量中,并使用该私有变量来设置 HttpHeader。

public class ClientHeaderPropagationInterceptor implements ClientHttpRequestInterceptor {

    @Value("${spring.application.name}")
    private String appName;

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        log.debug("ClientHeaderPropagationInterceptor in action");

        // Set source header for traceability between microservices
        log.debug("Setting request source to {}", appName);
        requestHeaders.set("source", appName);

        return execution.execute(request, body);
    }
}

但是我在上面的 appName 变量中得到了一个“null”值。这是因为拦截器在注入任何属性之前就被初始化了吗?任何建议将不胜感激。

Interceptor 类从注入 RestTemplate 的 @Bean 插入到 RestTemplate 生命周期中:

@Configuration
public class ApplicationConfig {

...
    @LoadBalanced
    @Bean(name = "loadBalancedRestTemplate")
    public RestTemplate getLoadBalancedRestTemplate(){
        RestTemplate restTemplate = new RestTemplate(customHttpRequestFactory());
        restTemplate.setErrorHandler(new CustomResponseHandler());
        restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        restTemplate.setInterceptors(Collections.singletonList(new ClientHeaderPropagationInterceptor()));
        return restTemplate;
    }
...
}

我可以确认拦截器确实运行了,因为我可以看到 log.debug 消息,但 appName 变量仍然为空。

4

1 回答 1

4

@Value不适用于非托管 spring bean。首先,您需要对其进行弹簧管理。尝试以下操作:

    @Bean
    public ClientHeaderPropagationInterceptor clientHeaderPropagationInterceptor() {
        return new ClientHeaderPropagationInterceptor();
    }

    @LoadBalanced
    @Bean(name = "loadBalancedRestTemplate")
    public RestTemplate getLoadBalancedRestTemplate(){
        RestTemplate restTemplate = new RestTemplate(customHttpRequestFactory());
        restTemplate.setErrorHandler(new CustomResponseHandler());
        restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        restTemplate.setInterceptors(Collections.singletonList(clientHeaderPropagationInterceptor()));
        return restTemplate;
    }
于 2017-05-28T06:20:58.507 回答