Spring Boot 番外 (02) - 自定义Condition
2019-09-12
Coding
Spring Boot
Spring
Java
👋 ‍️‍️阅读
❤️ 喜欢
💬 评论

Spring Boot 番外 (02) - 自定义Condition

Spring Boot提供了Condition接口来自定义Conditional。它只有一个方法

// 给定环境下,该Bean定义是否符合条件
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);

同时,对于每个Condition要定义对应的注解以标记Bean需要满足该条件。

这里我们依然以'世界'为例,在不同的世界里我们需要不同的Bean。

首先我们实现WorldCondition

public class WorldCondition implements Condition {

    static String WORLD_ID = "The World";

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // TODO 这里我们还没有定义注解,没有办法写检查条件的逻辑
    }
}

接着我们再定义对应的注解@OnWorld,指定WorldCondition为它的处理类

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Conditional(WorldCondition.class) //HL
public @interface OnWorld {
    String value();
}

然后我们回到WorldCondition中完成条件检查的逻辑

@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    String world = metadata.getAnnotationAttributes(OnWorld.class.getName())
                           .get("value").toString();
    return WORLD_ID.equals(world);
}

只有当前世界ID与指定的ID相同,则修饰的Bean才是有效的。

最后是我们的测试代码

public static void main(String[] args) {
    ConfigurableApplicationContext ctx1 = SpringApplication.run(Application.class, args);
    System.out.println(ctx1.getBean(BeanA.class));
    ctx1.close();

    WorldCondition.WORLD_ID = "Another World";

    ConfigurableApplicationContext ctx2 = SpringApplication.run(Application.class, args);
    System.out.println(ctx2.getBean(BeanA.class));
}

@Bean
@OnWorld("The World")
public static BeanA beanA1() {
    System.out.println("The world bean construct");
    return new BeanA();
}

@Bean
@OnWorld("Another World")
public static BeanA beanA2() {
    System.out.println("Another world bean construct");
    return new BeanA();
}

我们定义了两个BeanA,他们作用于不同的World。 我们run了两个容器,两次 World Id 不同,就会得到不同的BeanA

输出如下

// 1
The world bean construct
BeanA{world='The World'}
// 2
Another world bean construct
BeanA{world='Another World'}

Copyright © 2020-2022 Dean Xu. All Rights reserved.