SpringBoot之LazyInitializationBeanFactoryPostProcessor类源码学习
源码分析
/**
*
* @author Andy Wilkinson
* @author Madhura Bhave
* @author Tyler Van Gorder
* @author Phillip Webb
* @since 2.2.0
* @see LazyInitializationExcludeFilter
*
* 主要用于延迟初始化 Bean 的配置。它通过修改 BeanFactory 的配置来确保某些 Bean 在实际需要时才进行初始化,而不是在应用启动时就全部初始化。这有助于提高应用的启动速度和资源利用率。
*/
public final class LazyInitializationBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {
/**
* 在BeanFactory初始化后对bean进行后处理
* 主要用于处理延迟初始化相关的逻辑
*
* @param beanFactory ConfigurableListableBeanFactory类型的参数,代表BeanFactory
* @throws BeansException 如果处理过程中遇到错误,则抛出此异常
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// Take care not to force the eager init of factory beans when getting filters
//获取LazyInitializationExcludeFilter类型的bean
Collection<LazyInitializationExcludeFilter> filters = beanFactory
.getBeansOfType(LazyInitializationExcludeFilter.class, false, false).values();
//遍历容器中的所有bean定义
for (String beanName : beanFactory.getBeanDefinitionNames()) {
//根据beanName获取bean的定义
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
//检查bean定义是否为AbstractBeanDefinition类型
if (beanDefinition instanceof AbstractBeanDefinition) {
//如果是,则进行延迟初始化处理
postProcess(beanFactory, filters, beanName, (AbstractBeanDefinition) beanDefinition);
}
}
}
/**
* 根据条件更新bean的懒初始化状态
*
* @param beanFactory Bean工厂,用于获取bean的相关信息
* @param filters 排除懒初始化的过滤器集合
* @param beanName 当前bean的名称
* @param beanDefinition 当前bean的定义,包含懒初始化状态
*/
private void postProcess(ConfigurableListableBeanFactory beanFactory,
Collection<LazyInitializationExcludeFilter> filters, String beanName,
AbstractBeanDefinition beanDefinition) {
// 如果bean的懒初始化状态已明确,无需处理
Boolean lazyInit = beanDefinition.getLazyInit();
if (lazyInit != null) {
return;
}
// 获取bean的类型
Class<?> beanType = getBeanType(beanFactory, beanName);
//如果该bean不再filters列表中,则LazyInit设置为true
if (!isExcluded(filters, beanName, beanDefinition, beanType)) {
//给这个bean设置延迟初始化
beanDefinition.setLazyInit(true);
}
}
private Class<?> getBeanType(ConfigurableListableBeanFactory beanFactory, String beanName) {
try {
return beanFactory.getType(beanName, false);
}
catch (NoSuchBeanDefinitionException ex) {
return null;
}
}
/**
* 判断指定的bean是否被排除在懒初始化之外
*
* @param filters 一个包含多个排除过滤器的集合,用于判断bean是否应该被排除
* @param beanName bean的名称,用于在过滤时进行标识
* @param beanDefinition bean的定义信息,包含了bean的元数据
* @param beanType bean的类型,可能为null,用于类型级别的过滤
* @return 如果bean被至少一个过滤器认定为需要排除,则返回true;否则返回false
*/
private boolean isExcluded(Collection<LazyInitializationExcludeFilter> filters, String beanName,
AbstractBeanDefinition beanDefinition, Class<?> beanType) {
// 如果bean类型不为null,遍历所有过滤器以判断bean是否应被排除
if (beanType != null) {
for (LazyInitializationExcludeFilter filter : filters) {
// 如果当前过滤器认为bean应被排除,则直接返回true
if (filter.isExcluded(beanName, beanDefinition, beanType)) {
return true;
}
}
}
// 如果没有过滤器认为bean应被排除,则返回false
return false;
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
测试案例
class LazyInitializationExcludeFilterTests {
@Test
void forBeanTypesMatchesTypes() {
// 创建一个LazyInitializationExcludeFilter,排除CharSequence和Number类型的bean
LazyInitializationExcludeFilter filter = LazyInitializationExcludeFilter.forBeanTypes(CharSequence.class,
Number.class);
// 定义一个测试用的bean名称
String beanName = "test";
// 模拟一个BeanDefinition对象
BeanDefinition beanDefinition = mock(BeanDefinition.class);
// 验证filter是否正确排除了CharSequence类型
System.out.println("验证filter是否正确排除了CharSequence类型:"+filter.isExcluded(beanName, beanDefinition, CharSequence.class));
// 验证filter是否正确排除了String类型(CharSequence的子类型)
System.out.println("验证filter是否正确排除了String类型(CharSequence的子类型):"+filter.isExcluded(beanName, beanDefinition, String.class));
// 验证filter是否正确排除了StringBuilder类型(CharSequence的子类型)
System.out.println("验证filter是否正确排除了StringBuilder类型(CharSequence的子类型):"+filter.isExcluded(beanName, beanDefinition, StringBuilder.class));
// 验证filter是否正确排除了Number类型
System.out.println("验证filter是否正确排除了Number类型:"+filter.isExcluded(beanName, beanDefinition, Number.class));
// 验证filter是否正确排除了Long类型(Number的子类型)
System.out.println("验证filter是否正确排除了Long类型(Number的子类型):"+filter.isExcluded(beanName, beanDefinition, Long.class));
// 验证filter是否正确不排除Boolean类型(非Number类型)
System.out.println("验证filter是否正确不排除Boolean类型(非Number类型):"+filter.isExcluded(beanName, beanDefinition, Boolean.class));
}
}
测试结果
验证filter是否正确排除了CharSequence类型:true
验证filter是否正确排除了String类型(CharSequence的子类型):true
验证filter是否正确排除了StringBuilder类型(CharSequence的子类型):true
验证filter是否正确排除了Number类型:true
验证filter是否正确排除了Long类型(Number的子类型):true
验证filter是否正确不排除Boolean类型(非Number类型):false
原文地址:https://blog.csdn.net/weixin_44877172/article/details/145119559
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!