spring-boot - 如果 spring-cloud-stream 在类路径上,则 spring-boot 自动配置正在寻找默认绑定器
问题描述
我正在开发一个 spring-boot 多模块应用程序,我们正在创建一个自定义的 fat jar 来绑定所有第三方依赖项。这Spring cloud stream
也是这个脂肪罐的一部分。我们的应用程序在spring-cloud-stream
版本2.1.3.RELEASE
( spring-boot 2.1.6.RELEASE
) 上运行,我们正在将其升级到3.0.2.RELEASE
( spring-boot 2.2.4.RELEASE
)。我们在这里遇到了一个问题。如果一个特定的模块没有使用spring-cloud-stream
,但是spring-cloud-stream
在类路径上,那么 spring-bootauto-configuration
正在寻找一个default binder
.
{"mdc":{},"timestamp":"2020-03-20 12:53:04.150","level":"ERROR","logger":"org.springframework.boot.SpringApplication",
"message":"Application run failed", "exception":"\r\norg.springframework.context.ApplicationContextException:
Failed to start bean 'outputBindingLifecycle';
nested exception is java.lang.IllegalArgumentException: <b>A default binder has been requested, but there is no binder available</b>\r\n\
org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:185)\r\n\
org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:53)\r\n\
org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:360)\r\n\
org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:158)\r\n\
org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:122)\r\n\
org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:894)\r\n\
org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:162)\r\n\
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553)\r\n\
org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)\r\n\
org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)\r\n\
org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)\r\n\
org.springframework.boot.SpringApplication.run(SpringApplication.java:315)\r\n\
org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:126)\r\n\
org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal
(DefaultCacheAwareContextLoaderDelegate.java:99)\r\n\
org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)\r\n\
org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:123)\r\n\
org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.outputConditionEvaluationReport
(SpringBootDependencyInjectionTestExecutionListener.java:53)\r\n\
org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance
(SpringBootDependencyInjectionTestExecutionListener.java:46)\r\n\
org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:244)\r\n\
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)\r\n\
org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)\r\n\
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)\r\n\
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)\r\n\
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)\r\n\
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)\r\n\
org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)\r\n\
org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)\r\n\
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)\r\n\
org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)\r\n\
org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)\r\n\
org.springframework.test.context.junit4.s
ements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)\r\n\
org.springframework.test.context.junit4.s
ements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)\r\n\
org.junit.runners.ParentRunner.run(ParentRunner.java:363)\r\n\
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)\r\n\
org.junit.runner.JUnitCore.run(JUnitCore.java:137)\r\n\
org.junit.runner.JUnitCore.run(JUnitCore.java:115)\r\n\
org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:40)\r\n\
java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)\r\n\
java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)\r\n\
java.util.Iterator.forEachRemaining(Unknown Source)\r\n\
java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)\r\n\
java.util.stream.AbstractPipeline.copyInto(Unknown Source)\r\n\
java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)\r\n\
java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)\r\n\
java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)\r\n\
java.util.stream.AbstractPipeline.evaluate(Unknown Source)\r\n\
java.util.stream.ReferencePipeline.forEach(Unknown Source)\r\n\
org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:80)\r\n\
org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:71)\r\n\
org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)\r\n\
org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)\r\n\
org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)\r\n\
org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)\r\n\
org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:137)\r\n\
org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:89)\r\n\
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)\r\n\
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)\r\n\
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)\r\n\
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)\r\n\
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)\r\nCaused by:
java.lang.IllegalArgumentException: A default binder has been requested, but there is no binder
available\r\n\
org.springframework.util.Assert.notEmpty(Assert.java:549)\r\n\
org.springframework.cloud.stream.binder.DefaultBinderFactory.doGetBinder(DefaultBinderFactory.java:144)\r\n\
org.springframework.cloud.stream.binder.DefaultBinderFactory.getBinder(DefaultBinderFactory.java:134)\r\n\
org.springframework.cloud.stream.binding.BindingService.getBinder(BindingService.java:362)\r\n\
org.springframework.cloud.stream.binding.BindingService.bindProducer(BindingService.java:257)\r\n\
org.springframework.cloud.stream.binding.AbstractBindableProxyFactory.createAndBindOutputs(AbstractBindableProxyFactory.java:136)\r\n\
org.springframework.cloud.stream.binding.OutputBindingLifecycle.doStartWithBindable(OutputBindingLifecycle.java:58)\r\n\
java.util.LinkedHashMap$LinkedValues.forEach(Unknown Source)\r\n\
org.springframework.cloud.stream.binding.AbstractBindingLifecycle.start(AbstractBindingLifecycle.java:57)\r\n\
org.springframework.cloud.stream.binding.OutputBindingLifecycle.start(OutputBindingLifecycle.java:34)\r\n\
org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:182)\r\n\t... 59 common frames omitted\r\n\r\n"}
我们可以使用两种方法:-
- 没有用,
spring-cloud-stream
所以我可以spring-cloud-stream
从那个脂肪罐中排除,这样它就不会寻找任何粘合剂。 - 下面的依赖项提供了一个测试绑定器,因此无需实现真正的绑定器,我们就可以使用它来测试我们的应用程序。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream-test-support</artifactId> <version>3.0.2.RELEASE</version> <scope>test</scope> </dependency>
我想知道我是否可以在应用程序中使用任何其他方法或可配置属性,以便我可以停止寻找默认活页夹。
解决方案
我认为您使用这种方法违反了 spring-boot 原则,因此创建了非常大的 e JAR,这些 JAR 带有从未使用过的依赖项。当然,您可以使用exclude
属性@SpringBootApplication
并排除某些自动配置类。但我实际上是在问为什么在类路径上有一些永远不会使用的东西,不管这些东西是自动配置 JAR 还是只是库 JAR?此外,存在暂时的依赖关系,因此使用 sc-stream 您会带来许多其他 JAR,实际上可能会与您打算使用的东西产生冲突。
推荐阅读
- excel - 计算负值并对它们进行排名
- c++ - 向 ApplyGradientDescent 提供可变 alpha(学习率)
- python - 使用随机生成的、人类大小的、唯一的 id 创建模型实例
- python - 将零个或可变数量的值传递给 Click.Option
- jquery - 追加/删除到引导程序的末尾,单击时选择
- c++ - 由于具有循环引用的类中的 unique_ptr 或向量而导致核心转储
- laravel - Laravel - 如何将 MySQL 查询转换为 Laravel Eloquent
- java - 如何使用 Java 中的 ProcessBuilder 将字符串写入 cmd 提示符?
- c# - DropDownList Items.Clear 与绑定到空数据源
- python - 如何找到具有列数的每一行的最大值并打印它们?