关于 Spring 中如何按配置加载 Bean
约 538 字大约 2 分钟
2026-03-21
总所周知,Spring 在启动时会将 @Component 注解的类、@Configuration 下的 @Bean 注解的方法的返回值作为 Bean 注入到容器中实现 IOC 控制反转。 下图为 Mybatis-plus 的配置类,通过重写方法便捷的对创建、删除的用户和时间进行快速填充,其中在生产环境中直接使用 Spring Security 的上下文获取用户的 id 
但在测试环境中,尤其是单元测试下,并不会模拟用户的登录,只是需要在测试数据库中测试方法的 CRUD 逻辑,继续复用配置类必然会抛出空指针 因此很直接的想到在测试模块中编写一个新的配置类 
但出乎意料的,在测试模块中编写的配置类没有被正确调用,依然使用着生产环境的配置 
为什么
在测试模块中编写的 Bean 并不会被 Spring 所扫描,要想要实现自定义 Bean 的导入,需要同过@Import导入 
从 Spring 的启动阶段进行分析,首先 Spring 要知道有哪些 Bean,则需要扫描作用域内的 Bean,具体顺序为:@ComponentScan, @Import, @AutoConfiguration 对于扫描到的 Bean,Spring 使用 Map<String, BeanDefinition> 将它们一一存储。而问题就出现在这里,无论是生产代码还是测试代码的配置类,我们都没有主动为其编写 name,这就意味着两者在 Map 中是冲突的,而根据顺序后来者会覆盖前者,生效的自然只有生产环境下的代码
方案
对于不希望应用于测试模块中的 Bean,可以使用 @Profile("!test") 注解声明生效的配置域,此外在测试代码的 Spring 配置文件中声明当前激活的配置名,容器便能够自动屏蔽一些不应该在当前生效的 Bean 
