springboot08(自动配置Condition-01)
主旨:
1-springboot做的事情就是判断context.getBean("user"),是否有对应的字节码文件/对应的Bean
2-user是否有bean要看@Bean和@Conditional(ClassCondition.class)
3-Conditional(ClassCondition.class)里面的ClassCondition是一个类,里面重写方法进行判断
小知识点:config文件里面写Bean注解,一个文件只要定义成Bean才可以被SpringBoot发现并使用,所以Bean是重要的
一、在主程序写启动springboot应用,返回spring的IOC容器
和获取Bean和redisTemplate
@SpringBootApplication
public class SpringbootConditionApplication {
public static void main(String[] args) {
//启动springboot应用,返回spring的IOC容器
ConfigurableApplicationContext context = SpringApplication.run(SpringbootConditionApplication.class, args);
//获取Bean和redisTemplate
Object redisTemplate = context.getBean("redisTemplate");
System.out.println(redisTemplate);
}
}
二、上面的会报错,因为还没导入对应的依赖。接下来再pom.xml里面导入redis的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
三、用案例来理解一下:
- 案例:(判断是否有jedis这个坐标,有就加载User这个Bean,没有反之)
1-先创建User类,和UserConfig
-
(UserConfig是对User类的配置,such as:配置Bean之类的)
-
测试一下User类是否有配置Bean
@SpringBootApplication
public class SpringbootConditionApplication {
public static void main(String[] args) {
//启动springboot应用,返回spring的IOC容器
ConfigurableApplicationContext context = SpringApplication.run(SpringbootConditionApplication.class, args);
//获取Bean和redisTemplate
//Object redisTemplate = context.getBean("redisTemplate");
//System.out.println(redisTemplate);
Object user = context.getBean("user");
System.out.println(user);
}
}
User类
package com.itheima.springboot_condition.domain;
public class User {
}
UserConfig
@Configuration
public class UserConfig {
@Bean
public User user(){
return new User();
}
}
四、现在是直接可以获取User得Bean,但是我们的需求是加载jedis这个坐标,才加载User的Bean。
1-加@Conditional(ClassCondition.class)这个注解:
2-对@Conditional(ClassCondition.class)的分析:
- 这个里面的ClassCondition.class,是个单独的类,里面是对"字节码的判断"
3-ClassCondition这个类的创建和使用
-
创建:
-
ClassCondition代码:
public class ClassCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//需求1:判断是否导入jedis包,如果导入,就是true
//思路:判断redis.clients.jedis.Jedis.class是否存在
/*
拓展出来:
以后想知道某个坐标是否存在,或者想判断某个包的信息,也可以使用这个方法
*/
Boolean flag = true;
try {
Class<?> aClass = Class.forName("redis.clients.jedis.Jedis");
} catch (ClassNotFoundException e) {
flag = false;
}
return flag;
}
}
- 分析:为什么会有redis.clients.jedis.Jedis.class,并且去判断他是否存在
4- 为什么会存在redis.clients.jedis.Jedis.class,因为要在pom.xml里面导入这个坐标
redis坐标
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>
- 判断逻辑