当前位置: 首页 > news >正文

7、Spring之Bean生命周期~初始化

7、Spring之Bean生命周期~初始化

  • 初始化
    • invokeAwareMethods()方法
    • applyBeanPostProcessorsBeforeInitialization()方法
    • invokeInitMethods()方法
    • applyBeanPostProcessorsAfterInitialization()方法

初始化

  spring初始化分为三步:初始化前、初始化和初始化后,每一步作用也不相同,废话不多说,上代码:

/**
 * Initialize the given bean instance, applying factory callbacks
 * as well as init methods and bean post processors.
 * <p>Called from {@link #createBean} for traditionally defined beans,
 * and from {@link #initializeBean} for existing bean instances.
 *
 * @param beanName the bean name in the factory (for debugging purposes)
 * @param bean     the new bean instance we may need to initialize
 * @param mbd      the bean definition that the bean was created with
 *                 (can also be {@code null}, if given an existing bean instance)
 * @return the initialized bean instance (potentially wrapped)
 * @see BeanNameAware
 * @see BeanClassLoaderAware
 * @see BeanFactoryAware
 * @see #applyBeanPostProcessorsBeforeInitialization
 * @see #invokeInitMethods
 * @see #applyBeanPostProcessorsAfterInitialization
 */
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean);
			return null;
		}, getAccessControlContext());
	} else {

		invokeAwareMethods(beanName, bean);
	}

	Object wrappedBean = bean;

	// 初始化前
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}

	// 初始化
	try {
		invokeInitMethods(beanName, wrappedBean, mbd);
	} catch (Throwable ex) {
		throw new BeanCreationException(
				(mbd != null ? mbd.getResourceDescription() : null),
				beanName, "Invocation of init method failed", ex);
	}

	// 初始化后 AOP
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}

	return wrappedBean;
}

  通过上述代码,我们可以看到:

  1. 初始化方法的第一步会先调用invokeAwareMethods()方法进行Aware回调;
  2. 调用applyBeanPostProcessorsBeforeInitialization()方法完成初始化前操作;
  3. 调用invokeInitMethods()方法完成初始化操作;
  4. 调用applyBeanPostProcessorsAfterInitialization()方法完成初始化后操作;

invokeAwareMethods()方法

invokeAwareMethods()方法详解

private void invokeAwareMethods(String beanName, Object bean) {
	if (bean instanceof Aware) {
		// beanName回调
		if (bean instanceof BeanNameAware) {
			((BeanNameAware) bean).setBeanName(beanName);
		}
		// BeanClassLoader回调
		if (bean instanceof BeanClassLoaderAware) {
			ClassLoader bcl = getBeanClassLoader();
			if (bcl != null) {
				((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
			}
		}
		//BeanFactory回调
		if (bean instanceof BeanFactoryAware) {
			((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
		}
	}
}

  通过上述代码我们可以看到,这里会对BeanNameAware、BeanClassLoaderAware和BeanFactoryAware三个Aware接口进行回调操作;
  回调initializeBean()方法

applyBeanPostProcessorsBeforeInitialization()方法

applyBeanPostProcessorsBeforeInitialization()方法详解

	@Override
	public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

  这里我们可以看到,如果Bean有设置BeanPostProcessor接口的postProcessBeforeInitialization()方法在这里进行调用,Spring在这一步会判断bean对象有没有加@PostConstruct和@PreDestroy,如果有赋值给对应的属性,方便后续直接调用;
  回到initializeBean()方法

invokeInitMethods()方法

invokeInitMethods()方法详解

/**
 * Give a bean a chance to react now all its properties are set,
 * and a chance to know about its owning bean factory (this object).
 * This means checking whether the bean implements InitializingBean or defines
 * a custom init method, and invoking the necessary callback(s) if it does.
 *
 * @param beanName the bean name in the factory (for debugging purposes)
 * @param bean     the new bean instance we may need to initialize
 * @param mbd      the merged bean definition that the bean was created with
 *                 (can also be {@code null}, if given an existing bean instance)
 * @throws Throwable if thrown by init methods or by the invocation process
 * @see #invokeCustomInitMethod
 */
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
		throws Throwable {

	boolean isInitializingBean = (bean instanceof InitializingBean);
	if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
		if (logger.isTraceEnabled()) {
			logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
		}
		if (System.getSecurityManager() != null) {
			try {
				AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
					((InitializingBean) bean).afterPropertiesSet();
					return null;
				}, getAccessControlContext());
			} catch (PrivilegedActionException pae) {
				throw pae.getException();
			}
		} else {
			((InitializingBean) bean).afterPropertiesSet();
		}
	}

	if (mbd != null && bean.getClass() != NullBean.class) {
		String initMethodName = mbd.getInitMethodName();
		if (StringUtils.hasLength(initMethodName) &&
				!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
				!mbd.isExternallyManagedInitMethod(initMethodName)) {
			invokeCustomInitMethod(beanName, bean, mbd);
		}
	}
}

  这里可以看到,首先会判断当前Bean对象是否实现了InitializingBean接口,如果实现了就调用它的afterPropertiesSet()方法,然后判断BeanDefinition中是否指定初始化方法,如果指定啦初始化方法且不是afterPropertiesSet()方法的话,会调用BeanDefinition指定的初始化方法;
  回到initializeBean()方法

applyBeanPostProcessorsAfterInitialization()方法

applyBeanPostProcessorsAfterInitialization()方法详解

	@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;

		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

  如果Bean对象实现了BeanPostProcessor接口的postProcessAfterInitialization()方法进行初始化后设置,Spring中的AOP就是基于初始化后 实现的,初始化后返回的对象才是最终的Bean对象。
  回到initializeBean()方法

相关文章:

  • Linux内核 -- ftrace 调试工具培训
  • 【APP移动端自动化测试】第二节.Appium介绍和常用命令代码实现
  • PPT设置为本框的默认格式以及固定文本框
  • CorelDRAW2024官方最新中文破解版Crack安装包网盘下载安装方法
  • golang使用WaitGroup等待多个协程执行完成
  • 玄机靶场 第二章日志分析-mysql应急响应
  • 【运维】如何更换Ubuntu默认的Python版本,update-alternatives如何使用
  • 【设计模式深度剖析】【3】【行为型】【职责链模式】| 以购物中心客户服务流程为例加深理解
  • leetcode hot100 之 最长公共子序列
  • 工作总结1
  • 苹果WWDC 2024 带来的 AI 风暴:从生产力工具到个人助理,AI 将如何融入我们的生活?
  • Kotlin 委托
  • 面试Flask需要知道的知识点1
  • 【目标检测】基于深度学习的车牌识别管理系统(含UI界面)【python源码+Pyqt5界面 MX_002期】
  • 【Nginx系列】基于请求头的分发
  • Linux fallocate工具用于预分配或释放文件空间的块
  • 【qt】项目移植
  • pdf添加书签的软件,分享3个实用的软件!
  • LLVM Cpu0 新后端6
  • 【HarmonyOS】HUAWEI DevEco Studio 下载地址汇总
  • 网上诉讼服务平台/seo查询
  • 乐清开发网站公司/中国没有限制的搜索引擎
  • 仲恺建设局网站/汕头网站建设推广
  • 广东东莞自己建站教程/seo网站快速整站优化技术
  • 泸县城乡住房建设厅网站/sem工作原理
  • 在线客服中心/芜湖seo