Spring boot 为什么勇敢。追踪器不是自动连线的?

Spring boot 为什么勇敢。追踪器不是自动连线的?,spring-boot,zipkin,brave,Spring Boot,Zipkin,Brave,我们有很多使用SpringBoot2.0.x的服务,并且使用了io.zipkin.brave.Tracer,并且工作正常。Tracer用于一个用@Component注释的类,它有一个以Tracer作为参数的构造函数。 下面是一个示例片段: @Component public class CrmMessagePublisher { private static final Logger LOGGER = LoggerFactory.getLogger(CrmMessagePublishe

我们有很多使用SpringBoot2.0.x的服务,并且使用了
io.zipkin.brave.Tracer
,并且工作正常。Tracer用于一个用@Component注释的类,它有一个以Tracer作为参数的构造函数。 下面是一个示例片段:

@Component
public class CrmMessagePublisher {

    private static final Logger LOGGER = LoggerFactory.getLogger(CrmMessagePublisher.class);

    private static final String EVENT_NAME_HEADER = "service.eventName";

    private static final String EXCHANGE_EVENT = "service.event";

    private static String applicationName;

    private RabbitTemplate rabbitTemplate;

    @Autowired
    private Tracer tracer;

    @Autowired
    public CrmMessagePublisher(
            RabbitTemplate rabbitTemplate,
            @Value("${spring.application.name}") final String applicationName,
            Tracer tracer
    ) {
        this.rabbitTemplate = rabbitTemplate;
        CrmMessagePublisher.applicationName = applicationName;
        this.tracer = tracer;
    }
...
现在我想写一个junit测试,但我总是

Test ignored.

java.lang.IllegalStateException: Failed to load ApplicationContext

    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
    at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190)
    at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246)
    at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:97)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$invokeTestInstancePostProcessors$5(ClassTestDescriptor.java:349)
    at org.junit.jupiter.engine.descriptor.JupiterTestDescriptor.executeAndMaskThrowable(JupiterTestDescriptor.java:215)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$invokeTestInstancePostProcessors$6(ClassTestDescriptor.java:349)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1621)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
    at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
    at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.invokeTestInstancePostProcessors(ClassTestDescriptor.java:348)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.instantiateAndPostProcessTestInstance(ClassTestDescriptor.java:270)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$testInstanceProvider$2(ClassTestDescriptor.java:259)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$testInstanceProvider$3(ClassTestDescriptor.java:263)
    at java.base/java.util.Optional.orElseGet(Optional.java:362)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$testInstanceProvider$4(ClassTestDescriptor.java:262)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$before$0(ClassTestDescriptor.java:192)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.before(ClassTestDescriptor.java:191)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.before(ClassTestDescriptor.java:74)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:105)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:112)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220)
    at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188)
    at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'crmMessagePublisher': Unsatisfied dependency expressed through constructor parameter 2; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'brave.Tracer' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:769)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:218)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1341)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1187)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:847)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
    ... 48 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'brave.Tracer' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1662)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1221)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1175)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:857)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:760)
    ... 66 more
下面是测试类:

//@ExtendWith(SpringExtension.class)
@WebAppConfiguration
@ContextConfiguration(classes = {RabbitMqTest2.RabbitTestConfig.class, CrmMessagePublisher.class, Tracer.class})
////@EnableRabbit
@SpringBootTest
@TestPropertySource("classpath:application.properties")
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class RabbitMqTest2 {

    private final String QUEUE_NAME = "crm-test-service";

    @Autowired
    CachingConnectionFactory connectionFactory;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    private RabbitAdmin rabbitAdmin;

    private Binding binding;

    private Queue queue;

    @Autowired
    private CrmMessagePublisher publisher;
//    private Tracer tracer;

    @BeforeAll
    void beforeAll() {
        rabbitAdmin = new RabbitAdmin(this.connectionFactory);
    }

    @BeforeEach
    void beforeEachTestCase() {
        // TODO: Get values from test configuration
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        connectionFactory.setHost("localhost");
        connectionFactory.setPort(5672);

        rabbitTemplate = new RabbitTemplate(connectionFactory);

        rabbitTemplate.setDefaultReceiveQueue(QUEUE_NAME);  // for receiving messages
        rabbitTemplate.setRoutingKey(QUEUE_NAME); // for sending messages

        Properties queueProps = rabbitAdmin.getQueueProperties(QUEUE_NAME);
        if( queueProps == null ) {
            queue = new Queue(QUEUE_NAME, false, false, true);
            rabbitAdmin.declareQueue(queue);

            binding = BindingBuilder.bind(queue).to(new FanoutExchange("service.event"));
            rabbitAdmin.declareBinding(binding);
        }

        queueProps = rabbitAdmin.getQueueProperties(QUEUE_NAME);
        Assert.assertEquals("More messages than expected are in the queue.", 0,
                Integer.parseInt(queueProps.getProperty("QUEUE_MESSAGE_COUNT") == null ? "0" : queueProps.getProperty("QUEUE_MESSAGE_COUNT")));
    }

    @AfterEach
    void afterEachTestCase() {
        rabbitAdmin.removeBinding(binding);
        rabbitAdmin.deleteQueue(QUEUE_NAME);
    }

    @Test
    void sendMessageToQueue() throws JsonProcessingException {
        final CrmMessageModel message = new CrmMessageModel();
        message.setCustomerId(1L);
        final AmqpAdmin rabbitAdmin = new RabbitAdmin(this.rabbitTemplate.getConnectionFactory());
        final ObjectMapper om = new ObjectMapper();

        rabbitTemplate.convertAndSend("service.event", "contract-service", om.writeValueAsString(message));

        final Properties queueProps = rabbitAdmin.getQueueProperties(QUEUE_NAME);
        Assert.assertEquals("Not exactly ONE message is in the queue.", 1,
                Integer.parseInt(queueProps.get("QUEUE_MESSAGE_COUNT").toString()));
    }

    @Configuration
    public static class RabbitTestConfig extends ResourceServerConfigurerAdapter {

        @Bean
        public CachingConnectionFactory connectionFactory() {
            return new CachingConnectionFactory();
        }

        @Bean
        public RabbitTemplate crmRabbitTemplate() {
            return new RabbitTemplate(connectionFactory());
        }

        @Bean
        public RestTemplate crmRestTemplate() {
            return new RestTemplate();
        }

    }
}

那么:要成功运行测试,我必须做些什么?

问题是
@ContextConfiguration
中的tracer
tracer.class
实际上什么都不做:

  • 它不是
    @配置
  • 它没有带参数的构造函数,而spring可以自动连接这些参数

您应该改用
org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration.class
,它提供了一个可以自动连接的
Tracer
的工作实例;通过确保运行测试时
spring.sleuth.enabled=true来修复此问题。

请尝试从以下位置更改测试类行:

@ContextConfiguration(classes = {RabbitMqTest2.RabbitTestConfig.class, CrmMessagePublisher.class, Tracer.class})


brave.Tracer
是豆子吗?您在哪里配置跟踪程序?我根本不配置它。这是一个第三方类,它应该与第三方类CachingConnectionFactory一样工作。
@ContextConfiguration(classes = {RabbitMqTest2.RabbitTestConfig.class, CrmMessagePublisher.class, TraceAutoConfiguration.class})