我们写一个案例,内容:加入redis包存在我们注入一个User类,模拟一下自动配置Redis。然后再启动类中取一下
@Configuration public class UserConfig { @Bean @Conditional(MyCondition.class) //原生注解 public User user() { User user = new User(); user.setUsername("武大郎"); user.setId(1); return user; } } class MyCondition implements Condition { /* 根据当前环境中是否有RedisTemplate决定user bean 是否注入 RedisTemplate---取决于是否导入了redis starters */ @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { boolean flag = true; try { Class<?> aClass = Class.forName("org.springframework.data.redis.core.RedisTemplate"); } catch (ClassNotFoundException e) { e.printStackTrace(); flag = false; } return flag; } }
启动测试类运行一下,看一下结果
@SpringBootApplication @MapperScan("com.zys.springboot01.mapper") public class Springboot01Application { public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(Springboot01Application.class, args); Object user = applicationContext.getBean("user"); System.out.println("获取对象: " + user); } ..............
结果
使用反射去查看redis包是否存在,而重写的 matches() 方法返回值若为false则不加载User类,反之则加载,若搭配if判断就模拟了一个简单的自动配置。
衍生注解/派生注解
@Configuration //声明是一个配置
public class UserConfig {
/* @Bean public Apple apple(){ return new Apple(); } */ @Bean //@Conditional(MyCondition.class) //原生注解 /* 判断当前环境中是否有Apple Bean,如果有返回true, 不存在返回false */ //@ConditionalOnBean(Apple.class) /* 判断当前环境中是否有Apple Bean,如果有返回false, 不存在返回true */ //@ConditionalOnMissingBean(Apple.class) /* 判断当前环境中的配置文件中是否存在对应的key 和val */ //@ConditionalOnProperty(name = "itheima", havingValue = "33") /*
application.properties 中读取
判断当前环境中是否存在 Apple类,如果存在则返回true, 否则false */ @ConditionalOnClass(Apple.class) public User user(){ User user = new User(); user.setName("武大郎"); user.setAge(1); return user; } }
以上注解用于自动配置或特殊场景下是否记载某个或注入某个Spring组件
自动配置详细过程
在springboot源码中 详情转到 https://www.cnblogs.com/theRhyme/p/11057233.html#_lab2_3_2
在源码中加载时 AutoConfigurationImportSelector 类中有一个 方法
此方法加载了一个文件
此文件中的数据时所有自动配置类的全限定类名,截取一部分
在这个配置文件中声明了需要实现自动配置的类,并且全限定类名,接下来通过反射去创建初始化这些类,那么这些类里面一般添加了@Conditional相关注解,并且注解中的判断条件一般是当前环境中是否导入了相对应的依赖,如果存在则会启用自动配置。
我们这里还是以redis举例
第一个红框解释,判断是否有此依赖,有则加载配置。
第二个解释,查看用户是否自动注入了配置,有则使用用户的。