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

你可能感兴趣的:(SpringBoot,spring,boot,学习,java)