使用spring-boot-2,我想创建一个自定义自动配置,该动态配置定义动态数量的相同类型的bean。
例如,我有以下ConfigurationProperties
来定义AmazonS3
客户
@Setter
@Getter
@ConfigurationProperties("aws")
public class S3ClientProperties {
private Map<String, S3Config> s3 = new HashMap<>();
@Setter
@Getter
public static class S3Config {
private String accessKey;
private String secretKey;
private String bucketName;
private String region;
// ...
}
}
如果我有这样的Yaml:
aws.s3:
primary:
bucketName: bucket1
region: eu-west-1
secondary:
bucketName: bucket2
region: eu-east-1
最好将2个AmazonS3
类型的Bean注册到ApplicationContext
,一个名为primary
,一个名为secondary
。 >
除了在我的@PostContstruct
上放置@Configuration
,自动装配上下文并手动添加这些bean之外,还有其他更方便/更好的方法吗?
答案 0 :(得分:0)
您可以使用ConditionalOnProperty或多个条件,简单的例子(与您的yaml
一起使用):
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
Map<String, SomeService> someServiceBeans = context.getBeansOfType(SomeService.class);
someServiceBeans.forEach((key, value) ->
System.out.println("bean name: " + key + " ,bean class: " + value.getClass().getSimpleName()));
}
// some service
public interface SomeService {
}
// service if `aws.s3.primary` property exists
@Service("primaryService")
@ConditionalOnProperty("aws.s3.primary.bucketName")
public static class SomePrimaryService implements SomeService {
}
// service if `aws.s3.secondary` property exists
@Service("secondaryService")
@ConditionalOnProperty("aws.s3.secondary.bucketName")
public static class SomeSecondaryService implements SomeService {
}
// service if `SomeService` bean missing ( `aws.s3.primary` & `aws.s3.secondary` not exists )
@Service("defaultService")
@ConditionalOnMissingBean(SomeService.class)
public static class SomeDefaultService implements SomeService {
}
// service with `custom` condition and `class` condition (multiple conditions)
@Service("customService")
@ConditionalOnCustom
@ConditionalOnClass(SomeDefaultService.class)
public static class SomeCustomService implements SomeService {
}
// annotation for custom condition
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Conditional(CustomCondition.class)
public @interface ConditionalOnCustom {
}
// any custom condition
public static class CustomCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
// do something
return true;
}
}
}
应用程序输出:
bean name: customService ,bean class: SomeCustomService
bean name: primaryService ,bean class: SomePrimaryService
bean name: secondaryService ,bean class: SomeSecondaryService