我遇到过最令人费解的 Spring 错误消息,好吧,这些年来我遇到过一些,但这个应该记住。
错误信息是:
Field orderService in com.thalasoft.butik.rest.config.FixtureService required a single bean, but 2 were found:
- com.thalasoft.butik.data.service.OrderServiceImpl: defined in URL [jar:file:/home/stephane/.m2/repository/com/thalasoft/butik-data/0.0.1-SNAPSHOT/butik-data-0.0.1-SNAPSHOT.jar!/com/thalasoft/butik/data/service/OrderServiceImpl.class]
- OrderService: defined by method 'OrderService' in class path resource [com/thalasoft/butik/data/config/JpaService.class]
butik
应用程序由 2 个 Spring 项目组成,一个是 butik-data
项目,另一个是 butik-rest
项目。
在butik-rest
项目中运行集成测试时出现错误
mvn clean install -Denv="test" -Ddb="h2"
运行应用程序而不运行集成测试时会出现完全相同的错误:
mvn clean spring-boot:run
依赖项仅在 pom.xml
文件中存在一次:
<dependency>
<groupId>com.thalasoft</groupId>
<artifactId>butik-data</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
我的 butik-rest
项目配置如下:
@EnvProd
@SpringBootApplication
@Slf4j
public class Application implements CommandLineRunner {
@Component
@ComponentScan(nameGenerator = PackageBeanNameGenerator.class, basePackages = { "com.thalasoft.butik.rest.service", "com.thalasoft.butik.data" })
public class ApplicationConfiguration {
}
@Component
@EnableWebMvc
@EnableSpringDataWebSupport
@ComponentScan(nameGenerator = PackageBeanNameGenerator.class, basePackages = { "com.thalasoft.butik.rest.exception",
"com.thalasoft.butik.rest.controller", "com.thalasoft.butik.rest.assembler" })
public class WebConfiguration implements WebMvcConfigurer {
集成测试配置:
@RunWith(SpringRunner.class)
@Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = {
"classpath:mysql/clean-up-before-each-test.sql" })
public abstract class BaseTest {
@Configuration
@EnableAutoConfiguration
@ComponentScan(nameGenerator = PackageBeanNameGenerator.class, basePackages = { "com.thalasoft.butik.rest.config",
"com.thalasoft.butik.rest.service", "com.thalasoft.butik.data" })
public class TestConfiguration {
}
@EnableWebSecurity
@ComponentScan(nameGenerator = PackageBeanNameGenerator.class, basePackages = { "com.thalasoft.butik.rest.filter" })
public class NoSecurityConfiguration extends WebSecurityConfigurerAdapter {
服务 bean 在依赖项目中显式实例化:
@Configuration
public class JpaService {
@Bean
public ProductServiceImpl ProductService() {
return new ProductServiceImpl();
}
@Bean
public OrderServiceImpl OrderService() {
return new OrderServiceImpl();
}
}
会不会是 Spring 从 butik-data
项目中上面的显式实例化中获取了一个 bean,而从 "com.thalasoft.butik.data"
中获取了另一个 bean > 在依赖的 butik-rest
项目中扫描?
更新:即使将 "com.thalasoft.butik.data"
的两个实例(一个用于运行应用程序,另一个用于运行集成测试)更改为 "com.thalasoft.butik.data.config"
我仍然遇到同样的错误。
更新:我看到我犯了 2 个错误,使整个问题变得有点棘手。我还必须从集成测试中删除 "com.thalasoft.butik.data.config"
实例。现在问题消失了。
最佳答案
看起来您已经扫描了这两个位置。您需要调查当前扫描的地方和应该扫描的地方。
如果你认为当前的扫描方式(包括两个适合 Autowiring 'orderService'字段的bean),你可以通过注释标记其中一个bean @Primary(文档:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Primary.html) .
用这个注解标记的 Bean 将优先于其他注解,这应该可以解决您的问题。
祝你好运:)
关于java - 为什么我的依赖 Spring bean 被实例化了两次?一次来自 jar 依赖项,一次来自类路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53694997/