前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot配置-Condition

SpringBoot配置-Condition

作者头像
DataScience
发布2020-05-07 21:54:28
1.1K0
发布2020-05-07 21:54:28
举报
文章被收录于专栏:A2DataA2Data

Condition

条件 Spring4.0 增加条件判断得功能,实现选择性Bean创建的操作。

如果pom没有导入 data-redis配置 ,则会报错,程序包找不到。 Error:(12, 43) java: 程序包org.springframework.data.redis.core不存在

静态配置

那么如何判断是否引入呢?

  • 通过conditional来控制
  • 通过Condition 的matches 方法来控制 是否会被创建 创建User实体类。 创建UserConfig 创建ConditionClass

UserConfig

代码语言:java
复制
package a2data.cn.config;

import a2data.cn.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

/**
 *
 * @author JackFeng
 * @date 2020/4/21
 */


@Configuration
public class UserConfig {


    /**
     *  user的配置类,创建User相关的Bean
     * @return  new User()
     */
    @Bean
    @Conditional(ConditionClass.class)
    public User user(){
        return new User();
    }

}

ConditionClass

那么在此处,我们可以判断 是否导入jedis坐标来创建bean,可以灵活多变。判断对应文件 是否存在。

代码语言:java
复制
package a2data.cn.config;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

/**
 *
 * @author JackFeng
 * @date 2020/4/21
 */
public class ConditionClass implements Condition {

    /**
     * 按 Alt + Insert
     * 选择 implemnts 即可
     * @param context
     * @param metadata
     * @return  true/false  创建/不被创建
     */

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return false;
    }
}

判断jedis是否引入

引入依赖。 主要是:判断是否引入,class是否存在。

代码语言:html
复制
<!--d导入jedis坐标-->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>
代码语言:java
复制
package a2data.cn.config;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import redis.clients.jedis.Jedis;

/**
 *
 * @author JackFeng
 * @date 2020/4/21
 */
public class ConditionClass implements Condition {

    /**
     * 按 Alt + Insert
     * 选择 implemnts 即可
     * @param context
     * @param metadata
     * @return  true/false  创建/不被创建
     */

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

        // 引入jedis坐标后创建Bean,判断 redis.clients.jedis.Jedis.class 是否存在

        // 定义初始值
        boolean flag = true;

        try {
            Class<?> aClass = Class.forName("redis.clients.jedis.Jedis");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            flag = false;
        }
        return flag;
    }
}

动态配置

判断哪些注解是运行被创建的。

创建Annotation

代码语言:java
复制
package a2data.cn.config;

import org.springframework.context.annotation.Conditional;

import java.lang.annotation.*;

/**
 *
 * @author JackFeng
 * @date 2020/4/21
 */
// 我们自己定义的
// Taget 表示  加在哪个范围上,类,方法。
@Target({ElementType.TYPE, ElementType.METHOD})

// 注解生效的时机
@Retention(RetentionPolicy.RUNTIME)

// 生成javaDuc的文档
@Documented

// 上边的注解,通过点击Conditional 获得,放到自己定义的注解上边
@Conditional(ConditionClass.class)
public @interface ConditionOnClass {
    String[] value();
}

引入自定义配置

代码语言:java
复制
package a2data.cn.config;

import a2data.cn.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

/**
 *
 * @author JackFeng
 * @date 2020/4/21
 */


@Configuration
public class UserConfig {


    /**
     *  user的配置类,创建User相关的Bean
     * @return  new User()
     * @Conditional(ConditionClass.class)
     */
    @Bean
    // 想指定什么 指定什么
    @ConditionOnClass("redis.clients.jedis.Jedis")
    public User user(){

        return new User();
    }

}

上边的“redis.clients.jedis.Jedis” 还是写死的,如何灵活配置呢? 重点来了!!!

ConditionOnClass

代码语言:java
复制
package a2data.cn.config;

import org.springframework.context.annotation.Conditional;

import java.lang.annotation.*;

/**
 *
 * @author JackFeng
 * @date 2020/4/21
 */
// 我们自己定义的
// Taget 表示  加在哪个范围上,类,方法。
@Target({ElementType.TYPE, ElementType.METHOD})

// 注解生效的时机
@Retention(RetentionPolicy.RUNTIME)

// 生成javaDuc的文档
@Documented

// 上边的注解,通过点击Conditional 获得,放到自己定义的注解上边
@Conditional(ConditionClass.class)
public @interface ConditionOnClass {
    String[] value();
}

*Condition

代码语言:java
复制
package a2data.cn.config;

import jdk.nashorn.internal.ir.CallNode;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
import redis.clients.jedis.Jedis;

import java.util.Map;

/**
 *
 * @author JackFeng
 * @date 2020/4/21
 */
public class ConditionClass implements Condition {

    /**
     * 按 Alt + Insert
     * 选择 implemnts 即可
     * @param context  是上下对象,用于获取环境,IOC容器, ClassLader对象
     * @param metadata  注解的元对象, 可以用于获取注解定义的属性值
     * @return  true/false  创建/不被创建
     */

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

/*
        //配置文件的 配置属性
        Environment environment = context.getEnvironment();


        // 引入jedis坐标后创建Bean,判断 redis.clients.jedis.Jedis.class 是否存在

        // 定义初始值
        boolean flag = true;

        try {
            Class<?> aClass = Class.forName("redis.clients.jedis.Jedis");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            flag = false;
        }
        return flag;
        */


        // 导入指定坐标,通过在注解属性值 value ,才可以创建Bean
        // 获取注解属性值  value

        // metadata  --- 包名 类名 属性名
        Map<String, Object> map = metadata.getAnnotationAttributes(ConditionOnClass.class.getName());
        //System.out.println(map);

        String[] value = (String[]) map.get("value");

        boolean flag = true;

        try {

            // 快捷键 iter
            for (String claasName : value) {

                Class<?> cls = Class.forName(claasName);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            flag = false;
        }
        return flag;

    }
}

如下:

Property

根据自定义文件创建,从配置文件中获取。

UserConfig

代码语言:java
复制
package a2data.cn.config;

import a2data.cn.entity.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

/**
 *
 * @author JackFeng
 * @date 2020/4/21
 */


@Configuration
public class UserConfig {


    /**
     *  user的配置类,创建User相关的Bean
     * @return  new User()
     * @Conditional(ConditionClass.class)
     */
    @Bean
    @ConditionOnClass("redis.clients.jedis.Jedis")
    public User user(){

        return new User();
    }


    /**
     * 检查配置文件中,是否又a2data. DataScience
     * @return
     */
    @Bean
    @ConditionalOnProperty(name = "a2data",havingValue = "DataScience")

    public User user1(){
        return new User();
    }

}

MineProApplication

代码语言:java
复制
package a2data.cn;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 *
 * @author JackFeng
 * @date 2020/4/1
 */

/*
* 引导类
* */

@SpringBootApplication
public class MineProApplication {

    public static void main(String[] args) {

        //默认
//        SpringApplication.run(MineProApplication.class);
        // 启动spring boot的应用,返回spring的IOC容器


        ConfigurableApplicationContext context = SpringApplication.run(MineProApplication.class, args);
/*
        // 获取Bean,redisTeamplate
        Object redisTemplate = context.getBean("redisTemplate");
        System.out.println(redisTemplate + "公号DataScience");*/

//      获取User
        Object user = context.getBean("user");
        System.out.println(user);

        //获取User1
        Object user1 = context.getBean("user1");
        System.out.println("===============");
        System.out.println(user1);

    }

}

配置yml

代码语言:yaml
复制
# 自定义配置
a2data: DataScience

再次,运行,我们就发现正常了。

归纳总结

自定义:

  • 自定义类实现Condition接口,重写matches方法,
  • 判断条件@Conditional(条件类.class)注解

SpringBoot常用:

  • @ConditionalOnProperty
  • 判断配置文件中是否有对应属性值
  • @ConditionalOnClass
  • 判断环境中是否又对应字节码文件
  • @ConditionalOnMissingBean
  • 判断环境中有无对应Bean
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DataScience 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Condition
    • 静态配置
      • 动态配置
        • Property
          • 归纳总结
          相关产品与服务
          容器服务
          腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档