当你感觉轻松时,必然是有人在帮你抗住了生活的压力。
SpringBoot的自动配置
与Spring配置有关的注解
- @Profile
@Bean @Profile("dev") public DataSource dataSource1(){ return.... }
1.配置文件,比如在application.properties中声明、spring.profiles.active=dev
2.启动参数,比如-Dspring.profiles.active=dev
根据配置信息,选择@Profile(xxx)
哪一个生效,即注入到IOC容器中去。
这个Profile的概念很直观,但是由于它仅仅是依赖一个字符串的值作出决策,所以不够灵活和强大。因此就有了下面@Conditional注解和Condition接口的诞生。
- @Conditional()
Indicates that a component is only eligible for registration when all{@linkplain #value specified conditions} match
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
/**
* All {@link Condition}s that must {@linkplain Condition#matches match}
* in order for the component to be registered.
*/
Class extends Condition>[] value();
}
具体用法:在下面的例子中只有满足CustomCondition.class中的条件是这个bean才会被注册到IOC容器中去
@Configuration
public class CustomConfiguration {
// 当CustomCondition中的matches返回true的时候才会注入CustomClass这个类的实例Bean。
@Bean
@Conditional(CustomCondition.class)
public CustomClass customClass() {
return new CustomClass();
}
}
而上述例子中的CustomCondition实现了Condition接口
public interface Condition {
/**
* Determine if the condition matches.
* @param context the condition context
* @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class}
* or {@link org.springframework.core.type.MethodMetadata method} being checked
* @return {@code true} if the condition matches and the component can be registered,
* or {@code false} to veto the annotated component's registration
*/
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
A single {@code condition} that must be {@linkplain #matches matched} in order for a component to be registered.
public class CustomCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
......
return false;
}
}
根据具体算法规则,符合条件的返回true,即可以注册到容器中去,false就不注册。
概括:因此通过将@Conditional注解和Condition接口的能力进行结合,就可以实现根据外界条件来决定一个Bean是不是应该被加载到Spring上下文中。对比一下@Profile注解,可以发现这种方式提供了更高的灵活度。
在@Profile注解中,唯一决定是否加载一个Bean的是一个字符串,即所在环境的标识符例如DEV,TEST,PRODUCTION这类。但是在@Conditional的方案中,决定是否加载的逻辑被抽象到了Condition接口中,这样能够做的判断就非常多了。
@ConditionalOnClass
当类路径上存在指定的类时,满足条件。
@ConditionalOnProperty
当配置中存在指定的属性时,满足条件。
@ConfigurationProperties
@EnableConfigurationProperties
@ConfigurationProperties
Add this to a class definition or a {@code @Bean} method in a {@code @Configuration} class if you want to bind and validate some external Properties (e.g. from a .properties file)
@EnableConfigurationProperties
使用方法:@EnableConfigurationProperties(xxx.class)
xxx.class就是有@ConfigurationProperties
注解的class