Волшебная автоматическая настройка Spring Boot в основном опирается на большое количество условных аннотаций для использования автоматизации конфигурации.
Создает определенный компонент на основе выполнения определенного условия. Например, создать bean-компонент с некоторыми системными переменными или создать другой bean-компонент только после того, как bean-компонент будет создан, чтобы управлять поведением создания bean-компонента в соответствии с условиями, и вы можете использовать эту функцию для выполнения некоторой автоматической настройки.
1. Часто используемые условные аннотации
- @Conditional Зависит от условия
- @ConditionalOnBean при условии, что bean-компонент существует
- @ ConditionitionalonmissingBean В условии, что боба не существует
- @ConditionalOnClass при условии, что класс существует
- @ConditionalOnMissingClass при условии, что класс не существует
Эти аннотации более распространены, и есть и другие, такие как @ConditionalOnWebApplication, @ConditionalOnProperty и т. д. могут делать выводы друг из друга.
2. Специальное примечание @Conditional аннотация
@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, который является функциональным интерфейсом.
@FunctionalInterface
public interface Condition {
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
3. Пример условной аннотации
Пример сценария: динамическая настройка источника данных Mysql или Oracle в проекте
1. Определите файл конфигурации
db-type=mysql
2. Определите класс условия
MySqlCondition.java
public class MySqlCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return "mysql".equals(context.getEnvironment().getProperty("db-type"));
}
}
OracleCondition.java
public class OracleCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return "oracle".equals(context.getEnvironment().getProperty("db-type"));
}
}
Получить значение конфигурационного файла db-type
3. Интерфейс JdbcFactory
public interface JdbcFactory {
void create();
}
4. Реализации Mysql и Oracle по умолчанию
Mysql
@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 ..");
}
}
Oracle
@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..");
}
}
5. Протестируйте реализацию по умолчанию
@Resource
private JdbcFactory jdbcFactory;
@Test
public void conditionOnMissBean() {
jdbcFactory.create();
}
результат:
Default MySql create ..
6. Пользовательская реализация
@Component
public class MysqlFactory implements JdbcFactory {
@Override
public void create() {
System.out.println("mysql 。。 create");
}
}
7. Тест
@Resource
private JdbcFactory jdbcFactory;
@Test
public void conditionOnMissBean() {
jdbcFactory.create();
}
результат:
mysql 。。 create
8. Разобрать
Когда в среде нет JdbcFactory Bean, используется метод реализации по умолчанию.Например, когда нет пользовательской реализации, по умолчанию используется MySqlDefaultFactory. Это часто используется в автоматизированной конфигурации. Например, реализация redisTemplate по умолчанию