SpringBoot自定义AutoConfigurationImportFilter无法读取yml配置值如何解决
问题根因
AutoConfigurationImportFilter是Spring Boot启动极早期执行的扩展组件,执行match方法时,负责处理@Value注入、配置绑定的后置处理器还未完成初始化,因此@Value注解根本不会被解析,自然拿不到配置值。
这个阶段Spring已经完成了Environment的初始化,所有配置源(包括application.yml、启动参数、环境变量等)都已经加载完成,可以直接通过Environment读取配置,不需要依赖容器的注入能力。
解决步骤
- 去掉类里的
@Value注解,让过滤器实现EnvironmentAware接口,通过Aware回调拿到Environment实例,直接读取配置值 - 修正原
match方法的逻辑缺陷:原逻辑在配置开启数据库能力时会返回空列表,转换数组时会出现索引越界问题,直接遍历待匹配的自动配置类数组生成匹配结果即可
修正后完整代码
public class DatabaseExclusionFilter implements AutoConfigurationImportFilter, EnvironmentAware { private static final Set<String> DATABASE_BEANS_SKIP = new HashSet<>( Arrays.asList( "org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration", "org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration" ) ); private boolean databaseEnabled; @Override public void setEnvironment(Environment environment) { // 读取配置,默认值设为true,即未配置时默认加载数据库相关自动配置 this.databaseEnabled = environment.getProperty("database.enabled", Boolean.class, true); } @Override public boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata) { boolean[] result = new boolean[autoConfigurationClasses.length]; for (int i = 0; i < autoConfigurationClasses.length; i++) { String autoConfigClass = autoConfigurationClasses[i]; // 数据库开关关闭且当前类在排除列表中时,返回false表示不匹配(不加载该自动配置) result[i] = !(!databaseEnabled && DATABASE_BEANS_SKIP.contains(autoConfigClass)); } return result; } }
注意事项
- 原
spring.factories中的注册配置不需要修改,保持原有注册方式即可 - 该类属于Spring早期启动阶段的扩展组件,不要在其中注入任何需要容器初始化完成后才存在的业务Bean,否则会报找不到Bean的错误
- 读取配置时建议设置合理的默认值,避免配置缺失导致启动异常
内容的提问来源于stack exchange,提问作者Pedro Almeida
相关产品推荐
相关产品推荐

