SpringBoot是如何知道要创建哪个Bean的?比如Spring Boot是如何知道要创建RedisTemplate的?
Condition是在Spring4.0增加的条件判断功能,通过这个可以实现选择性的创建Bean操作。
在Spring的IOC容器中有一个User的Bean,现要求:
导入Jedis坐标后,加载该Bean,没导入,则不加载。
新建domain软件包,User 类:
package com.itheima.springbootcondition.domain;
public class User {
}
新建config软件包,UserConfig 类:
package com.itheima.springbootcondition.config;
import com.itheima.springbootcondition.condition.ClassCondition;
import com.itheima.springbootcondition.domain.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@Configuration
public class UserConfig {
@Bean
@Conditional(ClassCondition.class)
public User user(){
return new User();
}
}
新建condition软件包:ClassCondition类:
package com.itheima.springbootcondition.condition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class ClassCondition implements Condition {
/**
*
* @param context 上下文对象。用于获取环境,ioc容器,classloader对象
* @param metadata 注解元对象。用于获取注解定义的属性值。
* @return
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//需求1: 导入Jedis坐标后,加载该Bean,没导入,则不加载。
try {
Class> cls = Class.forName("redis.clients.jedis.Jedis");
} catch (ClassNotFoundException e) {
e.printStackTrace();
return false;
}
return true;
}
}
SpringbootConditionApplication类:
package com.itheima.springbootcondition;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class SpringbootConditionApplication {
public static void main(String[] args) {
//启动springboot的应用,返回spring的ioc容器
ConfigurableApplicationContext context = SpringApplication.run(SpringbootConditionApplication.class, args);
Object user = context.getBean("user");
System.out.println(user);
}
}
在pom文件里增删jedis坐标测试:
redis.clients
jedis
package com.itheima.springbootcondition.condition;
import org.springframework.context.annotation.Conditional;
import java.lang.annotation.*;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ClassCondition.class)
public @interface ConditionOnClass {
String[] value();
}
ClassCondition 类:
package com.itheima.springbootcondition.condition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import java.util.Iterator;
import java.util.Map;
public class ClassCondition implements Condition {
/**
*
* @param context 上下文对象。用于获取环境,ioc容器,classloader对象
* @param metadata 注解元对象。用于获取注解定义的属性值。
* @return
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//需求2:导入通过注解属性值value指定坐标后创建bean
//获取注解属性值 value
Map map = metadata.getAnnotationAttributes(ConditionOnClass.class.getName());
// System.out.println(map);
String[] value = (String[]) map.get("value");
try {
for (String classname : value) {
Class> cls = Class.forName(classname);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
return false;
}
return true;
}
}
UserConfig 类:
package com.itheima.springbootcondition.config;
import com.itheima.springbootcondition.condition.ClassCondition;
import com.itheima.springbootcondition.condition.ConditionOnClass;
import com.itheima.springbootcondition.domain.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@Configuration
public class UserConfig {
@Bean
// @Conditional(ClassCondition.class)
@ConditionOnClass("redis.clients.jedis.Jedis")
public User user(){
return new User();
}
}
在pom文件里增删jedis坐标测试。