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坐标测试:
- <dependency>
- <groupId>redis.clientsgroupId>
- <artifactId>jedisartifactId>
- dependency>
- 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坐标测试。
