@Configuration
表示这是一个配置类,是@Component的派生类,扫描到这个类时会它加入到IOC容器中
@ConfigurationProperties
将配置文件中对应的值和加了这个注解的类绑定起来
比如下面的HelloProperties类,初始化时会读取配置文件的spring.hello为前缀的属性与自己定义的字段关联
@ConfigurationProperties(prefix = "spring.hello")
//@Component
public class HelloProperties {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
spring.hello.name=b
spring.hello.age=1
@EnableConfigurationProperties
比如上面HelloProperties类,只加了@ConfigurationProperties注解,是不会被扫描加载到IOC容器中的,只有在HelloProperties类上加上@Component注解,或者使用@EnableConfigurationProperties(HelloProperties.class)注解HelloProperties类才会被IOC容器加载
@EnableConfigurationProperties(HelloProperties.class)作用
启动指定类的@ConfigurationProperties功能,将配置文件中对应的值和HelloProperties类绑定起来,并把HelloProperties加入到ioc容器中
@EnableConfigurationProperties需要加在配置类上(加了@Configuration的类,或@Component和其派生类上)
当HelloConfig类被容器扫描时,就会将HelloProperties加载到IOC容器中
@Configuration
@EnableConfigurationProperties(HelloProperties.class)
public class HelloConfig{
}
@Conditional注解的派生注解根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效
拿springboot中自动配置类,HttpEncodingAutoConfiguration做例子
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(HttpProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
private final HttpProperties.Encoding properties;
public HttpEncodingAutoConfiguration(HttpProperties properties) {
this.properties = properties.getEncoding();
}
@Bean
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
return filter;
}
...
}
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
判断当前应用是否是web应用,如果是,当前配置类生效(加载到IOC容器中),如果不是web应用,HttpEncodingAutoConfiguration类就不会被加载到IOC容器中
@ConditionalOnClass(CharacterEncodingFilter.class)
判断当前项目有没有CharacterEncodingFilter这个类(存不存在CharacterEncodingFilter.class文件),如果有,则Conditional条件判断为true(成立),当前HttpEncodingAutoConfiguration配置类生效
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
//判断配置文件中是否存在spring.http.encoding.enabled配置,matchIfMissing = true表示如果没有配置spring.http.encoding.enabled,也是满足Conditional的条件,HttpEncodingAutoConfiguration配置类生效也生效
@ConditionalOnMissingBean
上面的HttpEncodingAutoConfiguration把@ConditionalOnMissingBean用在加上@Bean的characterEncodingFilter方法上表示:如果当前项目中没有CharacterEncodingFilter这个bean(CharacterEncodingFilter类没有被初始化、未被加入到IOC容器中),则执行characterEncodingFilter方法初始化characterEncodingFilter,将其加入到IOC容器中
@ConditionalOnClass(CharacterEncodingFilter.class)和@ConditionalOnMissingBean的区别是
@ConditionalOnClass(CharacterEncodingFilter.class)是判断项目中是否存在CharacterEncodingFilter的类路径(是否存在CharacterEncodingFilter.class这个文件)
@ConditionalOnMissingBean是判断CharacterEncodingFilter这个类是否已经初始化了(是否已经加入到IOC容器中)
这里记录一些@Conditional派生的注解
@Conditional派生注解(Spring注解版原生的@Conditional作用)
作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;
@Conditional扩展注解 | 作用(判断是否满足当前指定条件) |
---|---|
@ConditionalOnJava | 系统的java版本是否符合要求 |
@ConditionalOnBean | 容器中存在指定Bean; |
@ConditionalOnMissingBean | 容器中不存在指定Bean; |
@ConditionalOnExpression | 满足SpEL表达式指定 |
@ConditionalOnClass | 系统中有指定的类 |
@ConditionalOnMissingClass | 系统中没有指定的类 |
@ConditionalOnSingleCandidate | 容器中只有一个指定的Bean,或者这个Bean是首选Bean |
@ConditionalOnProperty | 系统中指定的属性是否有指定的值 |
@ConditionalOnResource | 类路径下是否存在指定资源文件 |
@ConditionalOnWebApplication | 当前是web环境 |
@ConditionalOnNotWebApplication | 当前不是web环境 |
@ConditionalOnJndi | JNDI存在指定项 |