java - 为什么我的依赖 Spring bean 被实例化了两次?一次来自 jar 依赖项,一次来自类路径

标签 java spring spring-boot

我遇到过最令人费解的 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/

相关文章:

java - 安卓聊天客户端

java - Netflix Karyon 不使用 Governator 创建资源类

java - 使用构建器模式编码解码不可变对象(immutable对象)的最佳方法

javascript - 从rest服务获取JSON字符串到js

java - iBATIS - 请求和 session 范围

java - 通过 Selenium 中的 xpath 定位器匹配 div 的问题

java - 检查某个异常类型是否是嵌套异常中的原因(原因等)的最佳方法?

java - Bootstrap 选项卡在 Java/Spring Boot 应用程序中无法正常工作

java - 如何使用 Spring Boot Batch Job 更新数据库中的海量数据

java - 使用 Spring Boot 2.4.1 启动 Eureka Client 时出错