Spring 使用多个配置文件的启动注入问题
Spring Boot Injection issue using several Profiles
我在 Spring 中使用配置文件时遇到问题,基本上,我们使用它们来存根我们微服务的某些部分,它同时使用到数据库的连接和到另一个网络服务的连接。
之前我对数据库和外部网络服务都使用了一个存根配置文件:
@Configuration
@EnableAutoConfiguration
@Profile("stub")
@ComponentScan(
basePackages = {"com.consumption.backend"},
excludeFilters = {
@ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.consumption.backend.*.persistence.*"),
@ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.consumption.backend.databackendapi.*")
})
public class StubConfiguration {
@Bean
public DataApi consumptionApi() { return new DataStubApi(); }
@Bean
public RefDayDao refDayDao() { return new RefDayInMemoryDao(); }
@Bean
public RefTypeHourDao refTypeHourDao() { return new RefTypeHourInMemoryDao(); }
}
这工作正常,但是我想将这个存根分成两个存根,一个用于数据库,一个用于外部 Web 服务,以确保我们的测试具有更大的灵活性。
DAO 存根:
@Configuration
@EnableAutoConfiguration
@Profile("stubconfv3")
@ComponentScan(
basePackages = {"com.consumption.backend"},
excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.consumption.backend.*.persistence.*")
)
public class StubConfV3Configuration {
@Bean
public RefDayDao refDayDao() { return new RefDayInMemoryDao(); }
@Bean
public RefTypeHourDao refTypeHourDao() { return new RefTypeHourInMemoryDao(); }
}
外部网络服务存根:
@Configuration
@EnableAutoConfiguration
@Profile("stubdatabackend")
@ComponentScan(
basePackages = {"com.consumption.backend"},
excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.consumption.backend.databackendapi.*")
)
public class StubDataBackendConfiguration {
@Bean
public DataApi consumptionApi() { return new DataStubApi(); }
}
DAO 的存根似乎工作正常,但我似乎对外部 Web 服务有问题 API 不正确排除实施:
- 如果我使用
stub
配置文件启动我的应用程序,一切正常
- 如果我使用
stubconfv3
和 stubdatabackend
启动我的应用程序,我会遇到注入问题,因为发现了两个 classes :
Parameter 0 of constructor in
com.consumption.backend.service.DataService required a single bean,
but 2 were found:
dataBackendApi: defined in file [C:\code\consumption-backend\databackend-api\target\classes\com\consumption\backend\databackendapi\DataBackendApi.class]
consumptionApi: defined by method 'consumptionApi' in class path resource
[com/consumption/backend/application/configuration/StubDataBackendConfiguration.class]
Action:
Consider marking one of the beans as @Primary, updating the
consumer to accept multiple beans, or using @Qualifier to identify the
bean that should be consumed
排除不起作用或者有一些棘手的事情,因为它似乎在目标中找到 .class 文件,而不是在运行时在 class 加载程序中找到它
很可能,我犯了一些愚蠢的错误,但我没有看到...
编辑:我注意到如果我在 StubConfV3Configuration
中输入错误的 stubconfv3
配置文件,注入问题不会再出现,所以我猜你不能在 @ComponentScan
中组合 exclusionFilters两种不同的 classes...
第一个 class 将对除她排除的所有内容进行组件扫描,第二个将执行相同的操作,因此被第二个 class 排除的包仍然会被第一个 class 扫描。
您可以尝试使用
注释您的 DataBackendApi
@Profile("!stubdatabackend")
在不使用该配置文件时包含它,否则排除它
我在 Spring 中使用配置文件时遇到问题,基本上,我们使用它们来存根我们微服务的某些部分,它同时使用到数据库的连接和到另一个网络服务的连接。
之前我对数据库和外部网络服务都使用了一个存根配置文件:
@Configuration
@EnableAutoConfiguration
@Profile("stub")
@ComponentScan(
basePackages = {"com.consumption.backend"},
excludeFilters = {
@ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.consumption.backend.*.persistence.*"),
@ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.consumption.backend.databackendapi.*")
})
public class StubConfiguration {
@Bean
public DataApi consumptionApi() { return new DataStubApi(); }
@Bean
public RefDayDao refDayDao() { return new RefDayInMemoryDao(); }
@Bean
public RefTypeHourDao refTypeHourDao() { return new RefTypeHourInMemoryDao(); }
}
这工作正常,但是我想将这个存根分成两个存根,一个用于数据库,一个用于外部 Web 服务,以确保我们的测试具有更大的灵活性。
DAO 存根:
@Configuration
@EnableAutoConfiguration
@Profile("stubconfv3")
@ComponentScan(
basePackages = {"com.consumption.backend"},
excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.consumption.backend.*.persistence.*")
)
public class StubConfV3Configuration {
@Bean
public RefDayDao refDayDao() { return new RefDayInMemoryDao(); }
@Bean
public RefTypeHourDao refTypeHourDao() { return new RefTypeHourInMemoryDao(); }
}
外部网络服务存根:
@Configuration
@EnableAutoConfiguration
@Profile("stubdatabackend")
@ComponentScan(
basePackages = {"com.consumption.backend"},
excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.consumption.backend.databackendapi.*")
)
public class StubDataBackendConfiguration {
@Bean
public DataApi consumptionApi() { return new DataStubApi(); }
}
DAO 的存根似乎工作正常,但我似乎对外部 Web 服务有问题 API 不正确排除实施:
- 如果我使用
stub
配置文件启动我的应用程序,一切正常 - 如果我使用
stubconfv3
和stubdatabackend
启动我的应用程序,我会遇到注入问题,因为发现了两个 classes :
Parameter 0 of constructor in com.consumption.backend.service.DataService required a single bean, but 2 were found:
dataBackendApi: defined in file [C:\code\consumption-backend\databackend-api\target\classes\com\consumption\backend\databackendapi\DataBackendApi.class]
consumptionApi: defined by method 'consumptionApi' in class path resource [com/consumption/backend/application/configuration/StubDataBackendConfiguration.class]
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
排除不起作用或者有一些棘手的事情,因为它似乎在目标中找到 .class 文件,而不是在运行时在 class 加载程序中找到它
很可能,我犯了一些愚蠢的错误,但我没有看到...
编辑:我注意到如果我在 StubConfV3Configuration
中输入错误的 stubconfv3
配置文件,注入问题不会再出现,所以我猜你不能在 @ComponentScan
中组合 exclusionFilters两种不同的 classes...
第一个 class 将对除她排除的所有内容进行组件扫描,第二个将执行相同的操作,因此被第二个 class 排除的包仍然会被第一个 class 扫描。
您可以尝试使用
注释您的 DataBackendApi@Profile("!stubdatabackend")
在不使用该配置文件时包含它,否则排除它