spring注解驱动开发4-Conditional注解

37次阅读

共计 3450 个字符,预计需要花费 9 分钟才能阅读完成。

Conditional 注解

此注解用于配合 @Bean 注解, 限定 Bean 注解的条件: 如果满足条件, 响应的 Bean 才会放入容器; 否则不会!

springboot 大量应用此注解!

Conditional 注解能够在满足某条件时才初始化 Bean, 条件就是实现了 Condition 接口的 match 办法的逻辑! 本实例就是依据 VM option 运行时传入一个参数 -Dspring.profiles.active=xxx, 依据 xxx 是 dev 还是 product 来决定生成的对象 User 是 admin 还是 user01

(1). VM options 减少参数

-Dspring.profiles.active=product
(C:UsersweijuAppDataRoamingTyporatypora-user-imagesimage-20200713180310059.png)

(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);
}

(3). 输入:

User- 初始化!
conditionalConfig
uProduct
product
User{name=’user01′, passwd=’realP@sswd’, online=true}

(4). ConditionalConfig.java:

能够看到: 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);
    }
}

(5). 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 +
                '}';
    }
}

(6). 外围: 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;
    }
}

(7). 小结:

  1. @Conditional 注解能够配合 @Bean 注解, 在 Springboot 中大量利用!
  2. @Conditional 注解能够用于 办法 也能够用于类, 用在类上示意: 所有办法限定!!
  3. 须要标注具体的 Condition 实现类: 具体逻辑实现在 match 办法里! 不同的条件实现不同的 Condition 子类!

正文完
 0