

QQA: Spring Bean 如何开启懒加载
source link: https://lotabout.me/2021/QQA-how-to-lazy-initialize-spring-beans/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

有些 Bean 依赖外部环境,如 Repository 通常依赖数据库连接。一些单元测试中用不到它们,因此希望在测试中不初始化这些 Bean。除此之外,在测试中开启懒加载/延迟初始化(lazy-init),由于跳过了不用的 Bean,还能加快测试运行的速度。
Spring 2.2 之后
在 Spring 2.2 之后,最直接的方式是在 test/resources/application.yml
配置文件中加入如下参数:
spring.main.lazy-initialization: true
内部原理是在 SpringApplication
中,如果检测到该参数为真,则会创建一个
BeanFactoryPostProcessor,用于将“所有” BeanDefinition 的 lazyInit 属性置为真。
if (this.lazyInitialization) {
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
Spring 2.2 之前
参考这篇文章 ,本质上与 Spring 2.2 的方法一样,需要在测试包中自定义 BeanFactoryPostProcessor,用于将“所有” BeanDefinition 的 lazyInit 属性置为真:
@Component
@Profile("!" + TestLazyBeanInitConfiguration.EAGER_BEAN_INIT)
public class TestLazyBeanInitConfiguration implements BeanFactoryPostProcessor {
public static final String EAGER_BEAN_INIT = "eager-bean-init";
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
Arrays.stream(beanFactory.getBeanDefinitionNames())
.map(beanFactory::getBeanDefinition)
.forEach(beanDefinition -> beanDefinition.setLazyInit(true));
}
}
如果某个测试不需要懒加载,则通过注解 @ActiveProfiles(TestLazyBeanInitConfiguration.EAGER_BEAN_INIT)
关闭。
@ComponentScan(lazyInit = true) 有坑
通常我会在测试包中创建一个 TestApplication
类,并注解为
@SpringBootApplication
来完成 Bean 的自动扫描。尝试过下面的方式:
@SpringBootApplication
@ComponentScan(lazyInit = true)
public class TestApplication {
}
这种方法对于自动创建的 Bean(即标记为 @Component
, @Service
等的类)是有效的。但对于 Configuration
类中通过 @Bean
方式创建的 Bean 无效。毕竟
@ComponentScan
本身控制的就是扫描 Bean 的行为。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK