我们继续ConfigurationClassPostProcessor 处理@PropertySource(也会对@ConfigurationProperties、@Value进行分析)注解的流程,之前《springboot启动bean加载处理器ConfigurationClassPostProcessor 一(@ComponentScan注解)》简绍了这个类会处理**@PropertySource、 @ComponentScan、@Import、@ImportResource、@Bean**注解,本文就看下是怎么处理@PropertySource的,先看下源代码
class ConfigurationClassParser {
...
@Nullable
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// Recursively process any member (nested) classes first
processMemberClasses(configClass, sourceClass, filter);
}
// Process any @PropertySource annotations
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// Process any @ComponentScan annotations
// Process any @Import annotations
// Process any @ImportResource annotations
// Process individual @Bean methods
// Process default methods on interfaces
// Process superclass, if any
// No superclass -> processing is complete
return null;
}
}
很简单,这个注解的作用是往propertysources添加配置文件,之前我们简绍过《springboot启动之配置文件秘密》。
看下它的处理流程
- 判断当前类的是否有@PropertySources或@PropertySources注解,看下它的属性。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(PropertySources.class)
public @interface PropertySource {
//定义属性文件名称
String name() default "";
//定义扩展文件的路径
String[] value();
boolean ignoreResourceNotFound() default false;
String encoding() default "";
Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;
}
- 如果存在进入processPropertySource方法进行解析,获取我们定义的value值,如果是${xxx}类型,会先对值进行替换(从我们的配置文件中获取,也就是目前已经存在的propertysources)
- 加载资源文件Resource
- 添加到当前environment的propertySources中,注意是addLast,添加到最后。
看下具体的例子
@Configuration
@PropertySource("${property.additional.path}")
public class TestProperty {
private String name;
private String address;
public String getName() {
return name;
}