条件 Spring4.0 增加条件判断得功能,实现选择性Bean创建的操作。
如果pom没有导入
data-redis配置
,则会报错,程序包找不到。 Error:(12, 43) java: 程序包org.springframework.data.redis.core不存在
那么如何判断是否引入呢?
创建User实体类。
创建UserConfig
创建ConditionClass
UserConfig
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,可以灵活多变。判断对应文件 是否存在。
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是否存在。
<!--d导入jedis坐标-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
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
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();
}
引入自定义配置
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
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
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;
}
}
如下:
根据自定义文件创建,从配置文件中获取。
UserConfig
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
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
# 自定义配置
a2data: DataScience
再次,运行,我们就发现正常了。
自定义:
SpringBoot常用: