在Spring容器创建bean的时候也可以按照自定义的条件来决定创建哪些bean对象.@Conditional注解可以帮助实现此需求场景.
本篇模拟一下:在不同操作系统环境下创建不同的bean到容器中.
@Conditional注解的源码如下:
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Conditional { Class<? extends Condition>[] value(); }
可以发现此注解可以加在类上和方法上,注解中的值为class类型,且实现Condition接口.
创建两个自定义条件类:
public class MacConditional implements Condition { public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { //获取运行环境信息 Environment environment = context.getEnvironment(); String osName = environment.getProperty("os.name"); if(osName.contains("Mac")) {//如果在Mac系统下,返回true,即满足条件 return true ; } return false; } }
public class WindowsConditional implements Condition{ /** * ConditionContext,判断条件使用的上下文 * AnnotatedTypeMetadata,注释信息 */ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { //获取当前ioc的运行环境,以及环境配置 Environment environment = context.getEnvironment(); String osName = environment.getProperty("os.name"); if(osName.contains("Windows")) {//如果运行环境为Win,则满足条件 return true ; } return false; } }
自定义的条件类定义完以后,在配置类中的方法上添加@Conditional注解
@Configuration public class MainConfig2 { //如果为Windows环境则创建windows对象 @Conditional({WindowsConditional.class}) @Bean("windows") public Person getBill() { return new Person("windows操作系统",40) ; } //如果为Mac环境则创建mac对象 @Conditional({MacConditional.class}) @Bean("mac") public Person getlinux() { return new Person("mac",45) ; } }
测试类:
public class IOCTest { @Test public void test4() { ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class); String[] names = applicationContext.getBeanNamesForType(Person.class);//返回容器中所有bean的名字 for (String name : names) { System.out.println(name); } Map<String, Person> map = applicationContext.getBeansOfType(Person.class) ;//返回容器中的所有bean的对象 System.out.println(map); } }
运行结果:
mac
{mac=Person [name=mac, age=45]}
通过更改运行时的虚拟机配置,来更改操作系统
再次运行:
windows
{windows=Person [name=windows操作系统, age=40]}
扩展;
1,@Conditional注解还可以加在类上面.代表当满足条件是该配置类下的所有bean才会加载.
2,ConditionContext可以获取到很多信息,如类的注册信息,ioc工厂,获取类加载器等等