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

发布于:2024-06-11 ⋅ 阅读:(43) ⋅ 点赞:(0)

初始化

  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()方法


网站公告

今日签到

点亮在社区的每一天
去签到