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 new file mode 100644 index 000000000..632a6d306 --- /dev/null +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignContextBeanPostProcessor.java @@ -0,0 +1,62 @@ +/* + * Copyright 2013-2016 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 org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.cloud.netflix.feign.FeignContext; + +/** + * Post processor that wraps Feign Context in its tracing representations. + * + * @author Marcin Grzejszczak + * + * @since 1.0.2 + */ +final class FeignContextBeanPostProcessor implements BeanPostProcessor { + + private final BeanFactory beanFactory; + private TraceFeignObjectWrapper traceFeignObjectWrapper; + + FeignContextBeanPostProcessor(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + if (bean instanceof FeignContext) { + return new TraceFeignContext(getTraceFeignObjectWrapper(), + (FeignContext) bean); + } + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + TraceFeignObjectWrapper getTraceFeignObjectWrapper() { + if (this.traceFeignObjectWrapper == null) { + this.traceFeignObjectWrapper = this.beanFactory.getBean(TraceFeignObjectWrapper.class); + } + return this.traceFeignObjectWrapper; + } +} 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 74d0cb7d4..504af1167 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 @@ -18,8 +18,6 @@ package org.springframework.cloud.sleuth.instrument.web.client.feign; import java.io.IOException; import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.List; import com.netflix.hystrix.HystrixCommand; @@ -33,8 +31,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.web.HttpMessageConverters; import org.springframework.cloud.netflix.feign.FeignAutoConfiguration; -import org.springframework.cloud.netflix.feign.FeignClientSpecification; -import org.springframework.cloud.netflix.feign.FeignContext; import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder; import org.springframework.cloud.netflix.feign.support.SpringDecoder; import org.springframework.cloud.sleuth.SpanInjector; @@ -80,13 +76,18 @@ public class TraceFeignClientAutoConfiguration { } @Configuration + @ConditionalOnProperty(name = "spring.sleuth.feign.processor.enabled", matchIfMissing = true) protected static class FeignBeanPostProcessorConfiguration { @Bean - @ConditionalOnProperty(name = "spring.sleuth.feign.processor.enabled", matchIfMissing = true) FeignBeanPostProcessor feignBeanPostProcessor(TraceFeignObjectWrapper traceFeignObjectWrapper) { return new FeignBeanPostProcessor(traceFeignObjectWrapper); } + + @Bean + FeignContextBeanPostProcessor feignContextBeanPostProcessor(BeanFactory beanFactory) { + return new FeignContextBeanPostProcessor(beanFactory); + } } @Bean @@ -127,17 +128,6 @@ public class TraceFeignClientAutoConfiguration { return new TraceFeignRequestInterceptor(tracer, feignRequestTemplateInjector()); } - @Autowired(required = false) - private List configurations = new ArrayList<>(); - - @Bean - @Primary - FeignContext sleuthFeignContext(TraceFeignObjectWrapper traceFeignObjectWrapper) { - FeignContext feignContext = new TraceFeignContext(traceFeignObjectWrapper); - feignContext.setConfigurations(this.configurations); - return feignContext; - } - private SpanInjector feignRequestTemplateInjector() { return new FeignRequestTemplateInjector(); } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignContext.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignContext.java index c9f88e960..86f977737 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignContext.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignContext.java @@ -15,20 +15,23 @@ import org.springframework.cloud.netflix.feign.FeignContext; class TraceFeignContext extends FeignContext { private final TraceFeignObjectWrapper traceFeignObjectWrapper; + private final FeignContext delegate; - TraceFeignContext(TraceFeignObjectWrapper traceFeignObjectWrapper) { + TraceFeignContext(TraceFeignObjectWrapper traceFeignObjectWrapper, + FeignContext delegate) { this.traceFeignObjectWrapper = traceFeignObjectWrapper; + this.delegate = delegate; } @Override public T getInstance(String name, Class type) { - T object = super.getInstance(name, type); + T object = this.delegate.getInstance(name, type); return (T) this.traceFeignObjectWrapper.wrap(object); } @Override public Map getInstances(String name, Class type) { - Map instances = super.getInstances(name, type); + Map instances = this.delegate.getInstances(name, type); Map convertedInstances = new HashMap<>(); for (Map.Entry entry : instances.entrySet()) { convertedInstances.put(entry.getKey(), (T) this.traceFeignObjectWrapper.wrap(entry.getValue()));