From 2c611e9ab59ef3484661cd19fb86b295cf9756d5 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 28 Feb 2018 15:08:12 +0100 Subject: [PATCH] Made BPPs static beans, some of the config classes got infra role (#871) fixes gh-870 --- .../SleuthAnnotationAutoConfiguration.java | 8 ++- .../async/AsyncDefaultAutoConfiguration.java | 10 ++-- .../web/TraceWebServletAutoConfiguration.java | 2 +- .../TraceWebClientAutoConfiguration.java | 41 ++++++++++++---- .../feign/FeignContextBeanPostProcessor.java | 14 ++---- .../web/client/feign/LazyClient.java | 44 +++++++++++++++++ .../OkHttpFeignClientBeanPostProcessor.java | 15 ++---- .../web/client/feign/SleuthFeignBuilder.java | 2 +- .../feign/SleuthHystrixFeignBuilder.java | 2 +- .../TraceFeignClientAutoConfiguration.java | 4 +- .../zuul/TraceRibbonCommandFactory.java | 49 +++++++++++++++---- ...RibbonCommandFactoryBeanPostProcessor.java | 11 +---- .../zuul/TraceZuulAutoConfiguration.java | 4 +- .../log/SleuthLogAutoConfiguration.java | 4 +- .../instrument/web/client/GH846Test.java | 1 - .../TraceWebClientAutoConfigurationTests.java | 9 ++-- ...nCommandFactoryBeanPostProcessorTests.java | 9 +--- .../zuul/TraceRibbonCommandFactoryTest.java | 6 ++- 18 files changed, 157 insertions(+), 78 deletions(-) create mode 100644 spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyClient.java diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotationAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotationAutoConfiguration.java index 940af131a..624658035 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotationAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAnnotationAutoConfiguration.java @@ -16,6 +16,7 @@ package org.springframework.cloud.sleuth.annotation; import brave.Tracing; +import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -24,6 +25,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Role; /** * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration @@ -36,6 +38,7 @@ import org.springframework.context.annotation.Configuration; * @since 1.2.0 */ @Configuration +@Role(BeanDefinition.ROLE_INFRASTRUCTURE) @ConditionalOnBean(Tracing.class) @ConditionalOnProperty(name = "spring.sleuth.annotation.enabled", matchIfMissing = true) @AutoConfigureAfter(TraceAutoConfiguration.class) @@ -57,8 +60,9 @@ public class SleuthAnnotationAutoConfiguration { return new NoOpTagValueResolver(); } - @Bean SleuthAdvisorConfig sleuthAdvisorConfig() { + @Bean + @Role(BeanDefinition.ROLE_INFRASTRUCTURE) SleuthAdvisorConfig sleuthAdvisorConfig() { return new SleuthAdvisorConfig(); } - + } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncDefaultAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncDefaultAutoConfiguration.java index 57601a429..882e269d6 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncDefaultAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/async/AsyncDefaultAutoConfiguration.java @@ -22,6 +22,7 @@ import brave.Tracer; import brave.Tracing; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -29,6 +30,7 @@ import org.springframework.cloud.sleuth.SpanNamer; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Role; import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.scheduling.annotation.AsyncConfigurer; import org.springframework.scheduling.annotation.AsyncConfigurerSupport; @@ -47,14 +49,12 @@ import org.springframework.scheduling.annotation.AsyncConfigurerSupport; @Configuration @ConditionalOnProperty(value = "spring.sleuth.async.enabled", matchIfMissing = true) @ConditionalOnBean(Tracing.class) -//@AutoConfigureAfter(AsyncCustomAutoConfiguration.class) public class AsyncDefaultAutoConfiguration { - @Autowired private BeanFactory beanFactory; - @Configuration @ConditionalOnMissingBean(AsyncConfigurer.class) @ConditionalOnProperty(value = "spring.sleuth.async.configurer.enabled", matchIfMissing = true) + @Role(BeanDefinition.ROLE_INFRASTRUCTURE) static class DefaultAsyncConfigurerSupport extends AsyncConfigurerSupport { @Autowired private BeanFactory beanFactory; @@ -71,8 +71,8 @@ public class AsyncDefaultAutoConfiguration { } @Bean - public ExecutorBeanPostProcessor executorBeanPostProcessor() { - return new ExecutorBeanPostProcessor(this.beanFactory); + public static ExecutorBeanPostProcessor executorBeanPostProcessor(BeanFactory beanFactory) { + return new ExecutorBeanPostProcessor(beanFactory); } } \ No newline at end of file diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebServletAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebServletAutoConfiguration.java index acd2d4c61..0efbfed9f 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebServletAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebServletAutoConfiguration.java @@ -71,7 +71,7 @@ public class TraceWebServletAutoConfiguration { @Bean @ConditionalOnClass(name = "org.springframework.data.rest.webmvc.support.DelegatingHandlerMapping") - public TraceSpringDataBeanPostProcessor traceSpringDataBeanPostProcessor( + public static TraceSpringDataBeanPostProcessor traceSpringDataBeanPostProcessor( BeanFactory beanFactory) { return new TraceSpringDataBeanPostProcessor(beanFactory); } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java index da6b1914c..5f0699801 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java @@ -16,6 +16,7 @@ package org.springframework.cloud.sleuth.instrument.web.client; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -23,6 +24,7 @@ import brave.http.HttpTracing; import brave.spring.web.TracingClientHttpRequestInterceptor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.boot.autoconfigure.AutoConfigureAfter; @@ -33,7 +35,10 @@ import org.springframework.cloud.sleuth.instrument.web.TraceWebServletAutoConfig import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; +import org.springframework.http.HttpRequest; +import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.ClientHttpResponse; import org.springframework.web.client.RestTemplate; import org.springframework.web.reactive.function.client.WebClient; @@ -68,8 +73,8 @@ public class TraceWebClientAutoConfiguration { return new TraceRestTemplateCustomizer(this.clientInterceptor); } - @Bean TraceRestTemplateBPP traceRestTemplateBPP(BeanFactory beanFactory) { - return new TraceRestTemplateBPP(beanFactory); + @Bean static TraceRestTemplateBeanPostProcessor traceRestTemplateBPP(ListableBeanFactory beanFactory) { + return new TraceRestTemplateBeanPostProcessor(beanFactory); } } } @@ -77,17 +82,16 @@ public class TraceWebClientAutoConfiguration { @ConditionalOnClass(WebClient.class) static class WebClientConfig { - @Bean - TraceWebClientBeanPostProcessor traceWebClientBeanPostProcessor(BeanFactory beanFactory) { + @Bean static TraceWebClientBeanPostProcessor traceWebClientBeanPostProcessor(BeanFactory beanFactory) { return new TraceWebClientBeanPostProcessor(beanFactory); } } } class RestTemplateInterceptorInjector { - private final TracingClientHttpRequestInterceptor interceptor; + private final ClientHttpRequestInterceptor interceptor; - RestTemplateInterceptorInjector(TracingClientHttpRequestInterceptor interceptor) { + RestTemplateInterceptorInjector(ClientHttpRequestInterceptor interceptor) { this.interceptor = interceptor; } @@ -126,12 +130,11 @@ class TraceRestTemplateCustomizer implements RestTemplateCustomizer { } } -class TraceRestTemplateBPP implements BeanPostProcessor { +class TraceRestTemplateBeanPostProcessor implements BeanPostProcessor { private final BeanFactory beanFactory; - private TracingClientHttpRequestInterceptor interceptor; - TraceRestTemplateBPP(BeanFactory beanFactory) { + TraceRestTemplateBeanPostProcessor(BeanFactory beanFactory) { this.beanFactory = beanFactory; } @@ -149,6 +152,26 @@ class TraceRestTemplateBPP implements BeanPostProcessor { return bean; } + private LazyTracingClientHttpRequestInterceptor interceptor() { + return new LazyTracingClientHttpRequestInterceptor(this.beanFactory); + } + +} + +class LazyTracingClientHttpRequestInterceptor implements ClientHttpRequestInterceptor { + + private final BeanFactory beanFactory; + private TracingClientHttpRequestInterceptor interceptor; + + public LazyTracingClientHttpRequestInterceptor(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, + ClientHttpRequestExecution execution) throws IOException { + return interceptor().intercept(request, body, execution); + } + private TracingClientHttpRequestInterceptor interceptor() { if (this.interceptor == null) { this.interceptor = this.beanFactory.getBean(TracingClientHttpRequestInterceptor.class); diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignContextBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignContextBeanPostProcessor.java index 7f464e8d3..6f5b5652f 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignContextBeanPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignContextBeanPostProcessor.java @@ -31,7 +31,6 @@ import org.springframework.cloud.openfeign.FeignContext; final class FeignContextBeanPostProcessor implements BeanPostProcessor { private final BeanFactory beanFactory; - private TraceFeignObjectWrapper traceFeignObjectWrapper; FeignContextBeanPostProcessor(BeanFactory beanFactory) { this.beanFactory = beanFactory; @@ -40,22 +39,19 @@ final class FeignContextBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof FeignContext && !(bean instanceof TraceFeignContext)) { - return new TraceFeignContext(getTraceFeignObjectWrapper(), (FeignContext) bean); - } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof FeignContext && !(bean instanceof TraceFeignContext)) { + return new TraceFeignContext(traceFeignObjectWrapper(), (FeignContext) bean); + } return bean; } - private TraceFeignObjectWrapper getTraceFeignObjectWrapper() { - if (this.traceFeignObjectWrapper == null) { - this.traceFeignObjectWrapper = this.beanFactory.getBean(TraceFeignObjectWrapper.class); - } - return this.traceFeignObjectWrapper; + private TraceFeignObjectWrapper traceFeignObjectWrapper() { + return new TraceFeignObjectWrapper(this.beanFactory); } } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyClient.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyClient.java new file mode 100644 index 000000000..e589d346c --- /dev/null +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/LazyClient.java @@ -0,0 +1,44 @@ +/* + * Copyright 2013-2018 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 + * + * http://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.cloud.sleuth.instrument.web.client.feign; + +import java.io.IOException; + +import feign.Client; +import feign.Request; +import feign.Response; +import org.springframework.beans.factory.BeanFactory; + +class LazyClient implements Client { + + private final BeanFactory beanFactory; + private final Client delegate; + + LazyClient(BeanFactory beanFactory, Client delegate) { + this.beanFactory = beanFactory; + this.delegate = delegate; + } + + @Override public Response execute(Request request, Request.Options options) + throws IOException { + return ((Client) wrapper().wrap(this.delegate)).execute(request, options); + } + + private TraceFeignObjectWrapper wrapper() { + return new TraceFeignObjectWrapper(this.beanFactory); + } +} diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/OkHttpFeignClientBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/OkHttpFeignClientBeanPostProcessor.java index 51c992913..4c59cdfb7 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/OkHttpFeignClientBeanPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/OkHttpFeignClientBeanPostProcessor.java @@ -16,6 +16,7 @@ package org.springframework.cloud.sleuth.instrument.web.client.feign; +import feign.Client; import feign.okhttp.OkHttpClient; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; @@ -31,7 +32,6 @@ import org.springframework.beans.factory.config.BeanPostProcessor; final class OkHttpFeignClientBeanPostProcessor implements BeanPostProcessor { private final BeanFactory beanFactory; - private TraceFeignObjectWrapper traceFeignObjectWrapper; OkHttpFeignClientBeanPostProcessor(BeanFactory beanFactory) { this.beanFactory = beanFactory; @@ -40,8 +40,8 @@ final class OkHttpFeignClientBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof OkHttpClient) { - return getTraceFeignObjectWrapper().wrap(bean); + if (bean instanceof OkHttpClient && !(bean instanceof LazyClient)) { + return new LazyClient(this.beanFactory, (Client) bean); } return bean; } @@ -51,11 +51,4 @@ final class OkHttpFeignClientBeanPostProcessor implements BeanPostProcessor { throws BeansException { return bean; } - - private TraceFeignObjectWrapper getTraceFeignObjectWrapper() { - if (this.traceFeignObjectWrapper == null) { - this.traceFeignObjectWrapper = this.beanFactory.getBean(TraceFeignObjectWrapper.class); - } - return this.traceFeignObjectWrapper; - } -} +} \ No newline at end of file diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilder.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilder.java index 67804c213..7c0a2afca 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilder.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilder.java @@ -43,7 +43,7 @@ final class SleuthFeignBuilder { private static Client client(BeanFactory beanFactory) { try { Client client = beanFactory.getBean(Client.class); - return (Client) new TraceFeignObjectWrapper(beanFactory).wrap(client); + return new LazyClient(beanFactory, client); } catch (BeansException e) { return TracingFeignClient.create(beanFactory.getBean(HttpTracing.class), new Client.Default(null, null)); diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthHystrixFeignBuilder.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthHystrixFeignBuilder.java index 99a05e493..48d5ace1c 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthHystrixFeignBuilder.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthHystrixFeignBuilder.java @@ -45,7 +45,7 @@ final class SleuthHystrixFeignBuilder { private static Client client(BeanFactory beanFactory) { try { Client client = beanFactory.getBean(Client.class); - return (Client) new TraceFeignObjectWrapper(beanFactory).wrap(client); + return new LazyClient(beanFactory, client); } catch (BeansException e) { return TracingFeignClient.create(beanFactory.getBean(HttpTracing.class), new Client.Default(null, null)); diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java index 1c1ed1b54..ec9cde7e3 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java @@ -69,7 +69,7 @@ public class TraceFeignClientAutoConfiguration { @ConditionalOnProperty(name = "spring.sleuth.feign.processor.enabled", matchIfMissing = true) protected static class FeignBeanPostProcessorConfiguration { - @Bean FeignContextBeanPostProcessor feignContextBeanPostProcessor(BeanFactory beanFactory) { + @Bean static FeignContextBeanPostProcessor feignContextBeanPostProcessor(BeanFactory beanFactory) { return new FeignContextBeanPostProcessor(beanFactory); } } @@ -78,7 +78,7 @@ public class TraceFeignClientAutoConfiguration { @ConditionalOnClass(OkHttpClient.class) protected static class OkHttpClientFeignBeanPostProcessorConfiguration { - @Bean OkHttpFeignClientBeanPostProcessor okHttpFeignClientBeanPostProcessor(BeanFactory beanFactory) { + @Bean static OkHttpFeignClientBeanPostProcessor okHttpFeignClientBeanPostProcessor(BeanFactory beanFactory) { return new OkHttpFeignClientBeanPostProcessor(beanFactory); } } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRibbonCommandFactory.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRibbonCommandFactory.java index 03dbfb781..88892107b 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRibbonCommandFactory.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRibbonCommandFactory.java @@ -28,6 +28,8 @@ import brave.propagation.Propagation; import brave.propagation.TraceContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; @@ -41,7 +43,8 @@ import rx.Observable; * @author Marcin Grzejszczak * @since 1.1.0 */ -class TraceRibbonCommandFactory implements RibbonCommandFactory { +class TraceRibbonCommandFactory implements RibbonCommandFactory, + SmartInitializingSingleton { static final Propagation.Setter SETTER = new Propagation.Setter() { @Override public void put(RibbonCommandContext carrier, String key, String value) { @@ -55,23 +58,45 @@ class TraceRibbonCommandFactory implements RibbonCommandFactory { private static final Log log = LogFactory.getLog(TraceRibbonCommandFactory.class); - final HttpTracing tracing; - final Tracer tracer; - final RibbonCommandFactory delegate; + HttpTracing tracing; + Tracer tracer; + RibbonCommandFactory delegate; HttpClientHandler handler; TraceContext.Injector injector; + final BeanFactory beanFactory; - TraceRibbonCommandFactory(RibbonCommandFactory delegate, HttpTracing httpTracing) { - this.tracing = httpTracing; + TraceRibbonCommandFactory(RibbonCommandFactory delegate, BeanFactory beanFactory) { this.delegate = delegate; - this.tracer = httpTracing.tracing().tracer(); - this.handler = HttpClientHandler - .create(httpTracing, new TraceRibbonCommandFactory.HttpAdapter()); - this.injector = httpTracing.tracing().propagation().injector(SETTER); + this.beanFactory = beanFactory; + } + + private void initialize() { + if (this.tracing == null) { + this.tracing = httpTracing(); + } + if (this.tracer == null) { + this.tracer = httpTracing().tracing().tracer(); + } + if (this.handler == null) { + this.handler = HttpClientHandler + .create(httpTracing(), new TraceRibbonCommandFactory.HttpAdapter()); + } + if (this.injector == null) { + this.injector = httpTracing().tracing().propagation().injector(SETTER); + } + } + + private HttpTracing httpTracing() { + if (this.tracing == null) { + this.tracing = this.beanFactory.getBean(HttpTracing.class); + } + return this.tracing; } @Override public RibbonCommand create(final RibbonCommandContext context) { + // just in case - everything should be already initialized + initialize(); final RibbonCommand ribbonCommand = this.delegate.create(context); Span span = this.tracer.currentSpan(); if (log.isDebugEnabled()) { @@ -115,6 +140,10 @@ class TraceRibbonCommandFactory implements RibbonCommandFactory { .request(new TraceRibbonCommandFactory.HttpAdapter(), context, span); } + @Override public void afterSingletonsInstantiated() { + initialize(); + } + static final class HttpAdapter extends brave.http.HttpClientAdapter { diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRibbonCommandFactoryBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRibbonCommandFactoryBeanPostProcessor.java index 5bca66ad6..721efb6d8 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRibbonCommandFactoryBeanPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRibbonCommandFactoryBeanPostProcessor.java @@ -16,7 +16,6 @@ package org.springframework.cloud.sleuth.instrument.zuul; -import brave.http.HttpTracing; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.config.BeanPostProcessor; @@ -33,7 +32,6 @@ import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory final class TraceRibbonCommandFactoryBeanPostProcessor implements BeanPostProcessor { private final BeanFactory beanFactory; - private HttpTracing tracing; TraceRibbonCommandFactoryBeanPostProcessor(BeanFactory beanFactory) { this.beanFactory = beanFactory; @@ -50,15 +48,8 @@ final class TraceRibbonCommandFactoryBeanPostProcessor implements BeanPostProces throws BeansException { if (bean instanceof RibbonCommandFactory && !(bean instanceof TraceRibbonCommandFactory)) { - return new TraceRibbonCommandFactory((RibbonCommandFactory) bean, tracing()); + return new TraceRibbonCommandFactory((RibbonCommandFactory) bean, this.beanFactory); } return bean; } - - HttpTracing tracing() { - if (this.tracing == null) { - this.tracing = this.beanFactory.getBean(HttpTracing.class); - } - return this.tracing; - } } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulAutoConfiguration.java index cbfdb5cb2..5177e2eaa 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulAutoConfiguration.java @@ -51,13 +51,13 @@ public class TraceZuulAutoConfiguration { @ConditionalOnClass(RibbonCommand.class) static class RibbonConfig { @Bean - public TraceRibbonCommandFactoryBeanPostProcessor traceRibbonCommandFactoryBeanPostProcessor(BeanFactory beanFactory) { + static TraceRibbonCommandFactoryBeanPostProcessor traceRibbonCommandFactoryBeanPostProcessor(BeanFactory beanFactory) { return new TraceRibbonCommandFactoryBeanPostProcessor(beanFactory); } } @Bean - public TraceZuulHandlerMappingBeanPostProcessor traceHandlerMappingBeanPostProcessor(BeanFactory beanFactory) { + static TraceZuulHandlerMappingBeanPostProcessor traceHandlerMappingBeanPostProcessor(BeanFactory beanFactory) { return new TraceZuulHandlerMappingBeanPostProcessor(beanFactory); } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthLogAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthLogAutoConfiguration.java index 68e0a6550..b86d16631 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthLogAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthLogAutoConfiguration.java @@ -59,11 +59,11 @@ public class SleuthLogAutoConfiguration { @Bean @ConditionalOnProperty(value = "spring.sleuth.log.slf4j.enabled", matchIfMissing = true) @ConditionalOnBean(CurrentTraceContext.class) - public BeanPostProcessor slf4jSpanLoggerBPP() { + public static BeanPostProcessor slf4jSpanLoggerBPP() { return new Slf4jBeanPostProcessor(); } - class Slf4jBeanPostProcessor implements BeanPostProcessor { + static class Slf4jBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH846Test.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH846Test.java index 9944ad5a5..794b2031a 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH846Test.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/GH846Test.java @@ -58,7 +58,6 @@ public class GH846Test { } } - static class MyBean { @Autowired private RestTemplate restTemplate; diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfigurationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfigurationTests.java index 13c7ca6e4..33f77c18c 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfigurationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfigurationTests.java @@ -72,11 +72,14 @@ public class TraceWebClientAutoConfigurationTests { int myInterceptorIndex = -1; int mySecondInterceptorIndex = -1; for (int i = 0; i < interceptors.size(); i++) { - if (interceptors.get(i) instanceof TracingClientHttpRequestInterceptor) { + ClientHttpRequestInterceptor interceptor = interceptors + .get(i); + if (interceptor instanceof TracingClientHttpRequestInterceptor || + interceptor instanceof LazyTracingClientHttpRequestInterceptor) { traceInterceptorIndex = i; - } else if (interceptors.get(i) instanceof MyClientHttpRequestInterceptor) { + } else if (interceptor instanceof MyClientHttpRequestInterceptor) { myInterceptorIndex = i; - } else if (interceptors.get(i) instanceof MySecondClientHttpRequestInterceptor) { + } else if (interceptor instanceof MySecondClientHttpRequestInterceptor) { mySecondInterceptorIndex = i; } } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRibbonCommandFactoryBeanPostProcessorTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRibbonCommandFactoryBeanPostProcessorTests.java index c1f723690..920014f00 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRibbonCommandFactoryBeanPostProcessorTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRibbonCommandFactoryBeanPostProcessorTests.java @@ -19,10 +19,8 @@ package org.springframework.cloud.sleuth.instrument.zuul; import brave.Tracing; import brave.http.HttpTracing; import brave.propagation.CurrentTraceContext; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.BDDMockito; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; @@ -63,12 +61,7 @@ public class TraceRibbonCommandFactoryBeanPostProcessorTests { @Test public void should_wrap_ribbon_command_factory_in_a_trace_representation() { - then(this.postProcessor.postProcessAfterInitialization(ribbonCommandFactory, "name")).isInstanceOf( + then(this.postProcessor.postProcessAfterInitialization(this.ribbonCommandFactory, "name")).isInstanceOf( TraceRibbonCommandFactory.class); } - - @Before - public void setup() { - BDDMockito.given(this.beanFactory.getBean(HttpTracing.class)).willReturn(this.httpTracing); - } } \ No newline at end of file diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRibbonCommandFactoryTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRibbonCommandFactoryTest.java index 96245e235..d5fda83ff 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRibbonCommandFactoryTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRibbonCommandFactoryTest.java @@ -31,6 +31,7 @@ import org.junit.runner.RunWith; import org.mockito.BDDMockito; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.beans.factory.BeanFactory; import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; @@ -59,6 +60,7 @@ public class TraceRibbonCommandFactoryTest { .clientParser(SleuthHttpParserAccessor.getClient(this.traceKeys)) .serverParser(SleuthHttpParserAccessor.getServer(this.traceKeys, new ExceptionMessageErrorParser())) .build(); + @Mock BeanFactory beanFactory; @Mock RibbonCommandFactory ribbonCommandFactory; @Mock RibbonCommand ribbonCommand; TraceRibbonCommandFactory traceRibbonCommandFactory; @@ -67,8 +69,10 @@ public class TraceRibbonCommandFactoryTest { @Before @SuppressWarnings({ "deprecation", "unchecked" }) public void setup() { + BDDMockito.given(this.beanFactory.getBean(HttpTracing.class)) + .willReturn(this.httpTracing); this.traceRibbonCommandFactory = new TraceRibbonCommandFactory( - this.ribbonCommandFactory, this.httpTracing); + this.ribbonCommandFactory, this.beanFactory); BDDMockito.given(this.ribbonCommandFactory .create(BDDMockito.any(RibbonCommandContext.class))) .willReturn(this.ribbonCommand);