@Bean+@Conditional:
在满足某条件后才往spring容器中注入bean, 不满足则忽略!
Conditional注解可以在满足某条件时才初始化Bean, 条件就是实现了Condition接口的match方法的逻辑!本实例就是根据VM option运行时传入一个参数 -Dspring.profiles.active=xxx, 根据xxx是dev还是product来决定生成的对象User是 admin还是user01
-Dspring.profiles.active=product
2.测试代码:
@Test public void testConditinalBean() { ApplicationContext ctx = new AnnotationConfigApplicationContext(ConditionalConfig.class); Arrays.stream(ctx.getBeanDefinitionNames()).forEach(System.out::println); Environment environment = ctx.getEnvironment(); String profile = environment.getProperty("spring.profiles.active"); System.out.println(profile); User user = ctx.getBean(User.class); System.out.println(user); }
输出:
User-初始化!
conditionalConfig
uProduct
product
User{name='user01', passwd='realP@sswd', online=true}
可以看到: ConditionalConfig中, 使用了注解: @Conditional({ConditionalDev.class})
@Conditional({ConditionalProduct.class})
两个@Bean, 但是实际上初始化和输出的只有 product, 是-D参数的选择!!
package com.niewj.config; import com.niewj.bean.User; import com.niewj.condition.ConditionalDev; import com.niewj.condition.ConditionalProduct; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @Configuration public class ConditionalConfig { @Conditional({ConditionalDev.class}) @Bean("uDev") public User userDev(){ return new User("admin", "admin", false); } @Conditional({ConditionalProduct.class}) @Bean("uProduct") public User userProduct(){ return new User("user01", "realP@sswd", true); } }
4.User.java实体类:
package com.niewj.bean; import lombok.Data; @Data public class User { private String name; private String passwd; private boolean online ; public User(String name, String passwd, boolean online){ System.out.println("User-初始化!"); this.name = name; this.passwd = passwd; this.online = online; } @Override public String toString() { return "User{" + "name='" + name + '/'' + ", passwd='" + passwd + '/'' + ", online=" + online + '}'; } }
5.核心: Condition接口的具体实现两个: ConditionalDev + ConditionalProduct
package com.niewj.condition; import com.niewj.ConstUtil; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; /** * spring.profiles.active=dev 时满足条件 */ public class ConditionalDev implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { String profile = context.getEnvironment().getProperty(ConstUtil.PROFILES_ACTIVE); if (ConstUtil.DEV.equalsIgnoreCase(profile)) { return true; } return false; } }
ConditionalDev在条件: -Dspring.profiles.active=dev时返回true!
ConditionalProduct在条件: -Dspring.profiles.active=product时返回true!
可见, 可以根据某个传入参数来选择是否初始化某个Bean, 比如: 用来区分生产和dev环境~~
package com.niewj.condition; import com.niewj.ConstUtil; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; /** * profile=product 时满足条件 */ public class ConditionalProduct implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { String profile = context.getEnvironment().getProperty(ConstUtil.PROFILES_ACTIVE); if (ConstUtil.PRODUCT.equalsIgnoreCase(profile)) { return true; } return false; } }
小结: