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 3cf1cefa1..a8310d46e 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 @@ -15,6 +15,7 @@ */ package org.springframework.cloud.sleuth.annotation; +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.cloud.sleuth.Tracer; 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(Tracer.class) @ConditionalOnProperty(name = "spring.sleuth.annotation.enabled", matchIfMissing = true) @AutoConfigureAfter(TraceAutoConfiguration.class) @@ -61,8 +64,8 @@ public class SleuthAnnotationAutoConfiguration { } @Bean - SleuthAdvisorConfig sleuthAdvisorConfig() { + @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 1e8420171..25bd3bf0c 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 @@ -20,6 +20,7 @@ import java.util.concurrent.Executor; 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.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -28,6 +29,7 @@ import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; 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; @@ -49,11 +51,10 @@ import org.springframework.scheduling.annotation.AsyncConfigurerSupport; @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; @@ -64,14 +65,16 @@ public class AsyncDefaultAutoConfiguration { } } + @Autowired private BeanFactory beanFactory; + @Bean public TraceAsyncAspect traceAsyncAspect(Tracer tracer, TraceKeys traceKeys) { return new TraceAsyncAspect(tracer, traceKeys, this.beanFactory); } @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/TraceWebAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java index 8d5748152..f6b1913de 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java @@ -16,6 +16,7 @@ package org.springframework.cloud.sleuth.instrument.web; import org.springframework.beans.factory.BeanFactory; +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.ConditionalOnClass; @@ -30,6 +31,7 @@ import org.springframework.cloud.sleuth.Tracer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Role; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import static javax.servlet.DispatcherType.ASYNC; @@ -49,6 +51,7 @@ import static javax.servlet.DispatcherType.REQUEST; * @since 1.0.0 */ @Configuration +@Role(BeanDefinition.ROLE_INFRASTRUCTURE) @ConditionalOnProperty(value = "spring.sleuth.web.enabled", matchIfMissing = true) @ConditionalOnWebApplication @ConditionalOnBean(Tracer.class) 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 4255b8b86..629ad405a 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; @@ -37,7 +38,10 @@ import org.springframework.cloud.sleuth.instrument.web.TraceWebAutoConfiguration 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.security.oauth2.client.OAuth2RestTemplate; import org.springframework.web.client.RestTemplate; @@ -77,9 +81,8 @@ public class TraceWebClientAutoConfiguration { return new TraceRestTemplateCustomizer(this.traceRestTemplateInterceptor); } - @Bean - TraceRestTemplateBPP traceRestTemplateBPP(BeanFactory beanFactory) { - return new TraceRestTemplateBPP(beanFactory); + @Bean static TraceRestTemplateBeanPostProcessor traceRestTemplateBPP(BeanFactory beanFactory) { + return new TraceRestTemplateBeanPostProcessor(beanFactory); } } @@ -87,24 +90,21 @@ public class TraceWebClientAutoConfiguration { @ConditionalOnClass({ UserInfoRestTemplateCustomizer.class, OAuth2RestTemplate.class }) protected static class TraceOAuthConfiguration { - @Autowired BeanFactory beanFactory; - - @Bean - UserInfoRestTemplateCustomizerBPP userInfoRestTemplateCustomizerBeanPostProcessor() { - return new UserInfoRestTemplateCustomizerBPP(this.beanFactory); + @Bean static UserInfoRestTemplateCustomizerBeanPostProcessor userInfoRestTemplateCustomizerBeanPostProcessor(BeanFactory beanFactory) { + return new UserInfoRestTemplateCustomizerBeanPostProcessor(beanFactory); } @Bean @ConditionalOnMissingBean - UserInfoRestTemplateCustomizer traceUserInfoRestTemplateCustomizer() { - return new TraceUserInfoRestTemplateCustomizer(this.beanFactory); + UserInfoRestTemplateCustomizer traceUserInfoRestTemplateCustomizer(BeanFactory beanFactory) { + return new TraceUserInfoRestTemplateCustomizer(beanFactory); } - private static class UserInfoRestTemplateCustomizerBPP implements BeanPostProcessor { + private static class UserInfoRestTemplateCustomizerBeanPostProcessor implements BeanPostProcessor { private final BeanFactory beanFactory; - UserInfoRestTemplateCustomizerBPP(BeanFactory beanFactory) { + UserInfoRestTemplateCustomizerBeanPostProcessor(BeanFactory beanFactory) { this.beanFactory = beanFactory; } @@ -129,9 +129,9 @@ public class TraceWebClientAutoConfiguration { } class RestTemplateInterceptorInjector { - private final TraceRestTemplateInterceptor interceptor; + private final ClientHttpRequestInterceptor interceptor; - RestTemplateInterceptorInjector(TraceRestTemplateInterceptor interceptor) { + RestTemplateInterceptorInjector(ClientHttpRequestInterceptor interceptor) { this.interceptor = interceptor; } @@ -170,12 +170,12 @@ class TraceRestTemplateCustomizer implements RestTemplateCustomizer { } } -class TraceRestTemplateBPP implements BeanPostProcessor { +class TraceRestTemplateBeanPostProcessor implements BeanPostProcessor { private final BeanFactory beanFactory; private TraceRestTemplateInterceptor interceptor; - TraceRestTemplateBPP(BeanFactory beanFactory) { + TraceRestTemplateBeanPostProcessor(BeanFactory beanFactory) { this.beanFactory = beanFactory; } @@ -193,6 +193,26 @@ class TraceRestTemplateBPP implements BeanPostProcessor { return bean; } + private ClientHttpRequestInterceptor interceptor() { + return new LazyTracingClientHttpRequestInterceptor(this.beanFactory); + } + +} + +class LazyTracingClientHttpRequestInterceptor implements ClientHttpRequestInterceptor { + + private final BeanFactory beanFactory; + private TraceRestTemplateInterceptor 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 TraceRestTemplateInterceptor interceptor() { if (this.interceptor == null) { this.interceptor = this.beanFactory.getBean(TraceRestTemplateInterceptor.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 f17909087..58f8db61a 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.netflix.feign.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 6d12b43da..57a06c2f0 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,12 +16,12 @@ 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; import org.springframework.beans.factory.config.BeanPostProcessor; -import feign.okhttp.OkHttpClient; - /** * Post processor that wraps takes care of the OkHttp Feign Client instrumentation * @@ -32,7 +32,6 @@ import feign.okhttp.OkHttpClient; final class OkHttpFeignClientBeanPostProcessor implements BeanPostProcessor { private final BeanFactory beanFactory; - private TraceFeignObjectWrapper traceFeignObjectWrapper; OkHttpFeignClientBeanPostProcessor(BeanFactory beanFactory) { this.beanFactory = beanFactory; @@ -41,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; } @@ -52,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 226babb6c..ebaa1a04f 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 new TraceFeignClient(beanFactory); } 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 68a0274e6..d286e6f39 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 new TraceFeignClient(beanFactory); } 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 5b717e6a0..89e37de12 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 @@ -70,8 +70,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); } } @@ -80,8 +79,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 f64e121ae..ebcede510 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 @@ -16,6 +16,8 @@ package org.springframework.cloud.sleuth.instrument.zuul; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandContext; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; @@ -30,24 +32,39 @@ import org.springframework.cloud.sleuth.instrument.web.HttpTraceKeysInjector; * @author Marcin Grzejszczak * @since 1.1.0 */ -class TraceRibbonCommandFactory implements RibbonCommandFactory { +class TraceRibbonCommandFactory implements RibbonCommandFactory, + SmartInitializingSingleton { + private Tracer tracer; + private HttpTraceKeysInjector httpTraceKeysInjector; private final RibbonCommandFactory delegate; - private final Tracer tracer; - private final HttpTraceKeysInjector httpTraceKeysInjector; + private final BeanFactory beanFactory; - public TraceRibbonCommandFactory(RibbonCommandFactory delegate, - Tracer tracer, HttpTraceKeysInjector httpTraceKeysInjector) { + TraceRibbonCommandFactory(RibbonCommandFactory delegate, BeanFactory beanFactory) { + this.beanFactory = beanFactory; this.delegate = delegate; - this.tracer = tracer; - this.httpTraceKeysInjector = httpTraceKeysInjector; + } + + private void initialize() { + if (this.tracer == null) { + this.tracer = this.beanFactory.getBean(Tracer.class); + } + if (this.httpTraceKeysInjector == null) { + this.httpTraceKeysInjector = this.beanFactory.getBean(HttpTraceKeysInjector.class); + } } @Override public RibbonCommand create(RibbonCommandContext context) { + // just in case - everything should be already initialized + initialize(); RibbonCommand ribbonCommand = this.delegate.create(context); Span span = this.tracer.getCurrentSpan(); this.httpTraceKeysInjector.addRequestTags(span, context.uri(), context.getMethod()); return ribbonCommand; } + + @Override public void afterSingletonsInstantiated() { + initialize(); + } } 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 a506059d5..7d075d70b 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 @@ -20,8 +20,6 @@ import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.sleuth.Tracer; -import org.springframework.cloud.sleuth.instrument.web.HttpTraceKeysInjector; /** * Post processor that wraps a {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory} @@ -34,8 +32,6 @@ import org.springframework.cloud.sleuth.instrument.web.HttpTraceKeysInjector; final class TraceRibbonCommandFactoryBeanPostProcessor implements BeanPostProcessor { private final BeanFactory beanFactory; - private Tracer tracer; - private HttpTraceKeysInjector httpTraceKeysInjector; TraceRibbonCommandFactoryBeanPostProcessor(BeanFactory beanFactory) { this.beanFactory = beanFactory; @@ -44,8 +40,9 @@ final class TraceRibbonCommandFactoryBeanPostProcessor implements BeanPostProces @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof RibbonCommandFactory) { - return new TraceRibbonCommandFactory((RibbonCommandFactory) bean, getTracer(), getHttpTraceKeysInjector()); + if (bean instanceof RibbonCommandFactory + && !(bean instanceof TraceRibbonCommandFactory)) { + return new TraceRibbonCommandFactory((RibbonCommandFactory) bean, this.beanFactory); } return bean; } @@ -55,18 +52,4 @@ final class TraceRibbonCommandFactoryBeanPostProcessor implements BeanPostProces throws BeansException { return bean; } - - Tracer getTracer() { - if (this.tracer == null) { - this.tracer = this.beanFactory.getBean(Tracer.class); - } - return this.tracer; - } - - HttpTraceKeysInjector getHttpTraceKeysInjector() { - if (this.httpTraceKeysInjector == null) { - this.httpTraceKeysInjector = this.beanFactory.getBean(HttpTraceKeysInjector.class); - } - return this.httpTraceKeysInjector; - } } 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 f0b47c4a9..6ccc1fb92 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 @@ -68,7 +68,7 @@ public class TraceZuulAutoConfiguration { } @Bean - public TraceRibbonCommandFactoryBeanPostProcessor traceRibbonCommandFactoryBeanPostProcessor(BeanFactory beanFactory) { + public static TraceRibbonCommandFactoryBeanPostProcessor traceRibbonCommandFactoryBeanPostProcessor(BeanFactory beanFactory) { return new TraceRibbonCommandFactoryBeanPostProcessor(beanFactory); } @@ -91,7 +91,7 @@ public class TraceZuulAutoConfiguration { } @Bean - public TraceZuulHandlerMappingBeanPostProcessor traceHandlerMappingBeanPostProcessor(BeanFactory beanFactory) { + public static TraceZuulHandlerMappingBeanPostProcessor traceHandlerMappingBeanPostProcessor(BeanFactory beanFactory) { return new TraceZuulHandlerMappingBeanPostProcessor(beanFactory); } 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 0fc2add77..af5bd22ef 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 @@ -71,7 +71,8 @@ public class TraceWebClientAutoConfigurationTests { int myInterceptorIndex = -1; int mySecondInterceptorIndex = -1; for (int i = 0; i < interceptors.size(); i++) { - if (interceptors.get(i) instanceof TraceRestTemplateInterceptor) { + if (interceptors.get(i) instanceof TraceRestTemplateInterceptor || + interceptors.get(i) instanceof LazyTracingClientHttpRequestInterceptor) { traceInterceptorIndex = i; } else if (interceptors.get(i) instanceof MyClientHttpRequestInterceptor) { myInterceptorIndex = i; 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 95f246639..b52d4b3c2 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 @@ -24,6 +24,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.beans.factory.BeanFactory; import org.springframework.cloud.netflix.ribbon.SpringClientFactory; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandContext; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; @@ -51,6 +52,7 @@ public class TraceRibbonCommandFactoryTest { @Mock Tracer tracer; @Mock SpringClientFactory springClientFactory; + @Mock BeanFactory beanFactory; HttpTraceKeysInjector httpTraceKeysInjector; @Mock RibbonCommandFactory ribbonCommandFactory; TraceRibbonCommandFactory traceRibbonCommandFactory; @@ -62,12 +64,15 @@ public class TraceRibbonCommandFactoryTest { public void setup() { this.httpTraceKeysInjector = new HttpTraceKeysInjector(this.tracer, new TraceKeys()); this.traceRibbonCommandFactory = new TraceRibbonCommandFactory( - this.ribbonCommandFactory, this.tracer, - httpTraceKeysInjector); + this.ribbonCommandFactory, this.beanFactory); given(this.springClientFactory.getClient(anyString(), any(Class.class))) .willReturn(new RestClient()); given(this.tracer.getCurrentSpan()).willReturn(span); given(this.tracer.isTracing()).willReturn(true); + given(this.beanFactory.getBean(Tracer.class)) + .willReturn(this.tracer); + given(this.beanFactory.getBean(HttpTraceKeysInjector.class)) + .willReturn(this.httpTraceKeysInjector); } @After diff --git a/spring-cloud-sleuth-stream/src/main/java/org/springframework/cloud/sleuth/stream/SleuthStreamAutoConfiguration.java b/spring-cloud-sleuth-stream/src/main/java/org/springframework/cloud/sleuth/stream/SleuthStreamAutoConfiguration.java index 7d04f2adc..4fdeab80d 100644 --- a/spring-cloud-sleuth-stream/src/main/java/org/springframework/cloud/sleuth/stream/SleuthStreamAutoConfiguration.java +++ b/spring-cloud-sleuth-stream/src/main/java/org/springframework/cloud/sleuth/stream/SleuthStreamAutoConfiguration.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -45,6 +46,7 @@ import org.springframework.cloud.stream.config.ChannelBindingAutoConfiguration; import org.springframework.cloud.stream.config.ChannelsEndpointAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Role; import org.springframework.core.Ordered; import org.springframework.core.env.Environment; import org.springframework.integration.config.GlobalChannelInterceptor; @@ -102,6 +104,7 @@ public class SleuthStreamAutoConfiguration { @Bean @ConditionalOnMissingBean + @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public StreamSpanReporter sleuthStreamSpanReporter(HostLocator endpointLocator, SpanMetricReporter spanMetricReporter, Environment environment) { return new StreamSpanReporter(endpointLocator, spanMetricReporter, environment,