Spring Boot 神奇的自动配置,主要依靠大量的条件注解来使用配置自动化。java
根据知足某一个特定条件建立一个特定的Bean。好比说,在某些系统变量下建立Bean,或者只有在某个Bean建立后才去建立另一个Bean. 就是根据条件来控制Bean的建立行为,能够利用该特性来进行一些自动配置。mysql
比较常见的是这些注解,还有其它的好比 @ConditionalOnWebApplication, @ConditionalOnProperty 等,可触类旁通git
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Conditional { /** * All {@link Condition Conditions} that must {@linkplain Condition#matches match} * in order for the component to be registered. */ Class<? extends Condition>[] value(); }
使用@Conditional注解,对象须要实现Condition接口,Condition 接口是一个函数式接口github
@FunctionalInterface public interface Condition { boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata); }
示例场景:项目中动态的配置Mysql或者Oracle数据源redis
db-type=oracle
MySqlCondition.javaspring
public class MySqlCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return "mysql".equals(context.getEnvironment().getProperty("db-type")); } }
OracleCondition.javasql
public class OracleCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return "oracle".equals(context.getEnvironment().getProperty("db-type")); } }
获取配置文件db-type的值springboot
public interface JdbcFactory { void create(); }
Mysqloracle
@ConditionalOnMissingBean(value = JdbcFactory.class, ignored = MySqlDefaultFactory.class) @Conditional(MySqlCondition.class) @Component public class MySqlDefaultFactory implements JdbcFactory { @Override public void create() { System.out.println("Default MySql create .."); } }
Oracleide
@ConditionalOnMissingBean(value = JdbcFactory.class, ignored = OracleDefaultFactory.class) @Conditional(OracleCondition.class) @Component public class OracleDefaultFactory implements JdbcFactory { @Override public void create() { System.out.println("Default oracle create.."); } }
@Resource private JdbcFactory jdbcFactory; @Test public void conditionOnMissBean() { jdbcFactory.create(); }
结果:
Default MySql create ..
@Component public class MysqlFactory implements JdbcFactory { @Override public void create() { System.out.println("mysql 。。 create"); } }
@Resource private JdbcFactory jdbcFactory; @Test public void conditionOnMissBean() { jdbcFactory.create(); }
结果:
mysql 。。 create
当环境中不存在 JdbcFactory 的Bean时则使用默认的实现的方式,如例:没有自定义实现时,则默认使用MySqlDefaultFactory。这在自动化配置中会常常用到。好比redisTemplate 的默认实现