欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring - Bean 的初始化过程

程序员文章站 2022-05-21 22:14:09
...

Spring - Bean 的初始化过程


1、创建一个Bean

@Component
public class OnBean {
}

2、让该Bean 实现Spring 的一些钩子函数

@Slf4j
@Component
public class OnBean
    implements BeanNameAware,
        BeanFactoryAware,
        ApplicationContextAware,
        BeanPostProcessor,
        InitializingBean,
        DisposableBean {

  private String beanName;
  private BeanFactory beanFactory;
  private ApplicationContext applicationContext;

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    log.info("ApplicationContextAware.setApplicationContext");
    this.applicationContext = applicationContext;
  }

  @Override
  public void setBeanName(String s) {
    log.info("BeanNameAware.setBeanName");
    this.beanName = s;
  }

  @Override
  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    log.info("BeanFactoryAware.setBeanFactory");
    this.beanFactory = beanFactory;
  }

  @Override
  public void destroy() throws Exception {
    log.info("DisposableBean.destroy");
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    log.info("InitializingBean.afterPropertiesSet");
  }

  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName)
      throws BeansException {
    // log.info("所有bean 都会调用本方法 post Process Before Initialization");
    return null;
  }

  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    // log.info("所有bean 都会调用本方法 post Process After Initialization");
    return null;
  }

  @PostConstruct
  void init() {
    log.info("init");
  }

  @PreDestroy
  void destory() {
    log.info("destory");
  }
}

3、追踪bean 的初始化过程

2019-09-01 22:08:33.134  INFO 68840 --- [           main] com.wretchant.timer.OnBean               : BeanNameAware.setBeanName
2019-09-01 22:08:33.134  INFO 68840 --- [           main] com.wretchant.timer.OnBean               : BeanFactoryAware.setBeanFactory
2019-09-01 22:08:33.134  INFO 68840 --- [           main] com.wretchant.timer.OnBean               : ApplicationContextAware.setApplicationContext
2019-09-01 22:08:33.134  INFO 68840 --- [           main] com.wretchant.timer.OnBean               : init
2019-09-01 22:08:33.135  INFO 68840 --- [           main] com.wretchant.timer.OnBean               : InitializingBean.afterPropertiesSet

执行顺序

  • BeanNameAware.setBeanName
  • BeanFactoryAware.setBeanFactory
  • ApplicationContextAware.setApplicationContext
  • @PostConstruct
  • InitializingBean.afterPropertiesSet
  • BeanPostProcessor.postProcessBeforeInitialization
  • BeanPostProcessor.postProcessAfterInitialization

销毁时

2019-09-01 22:13:10.272  INFO 111588 --- [       Thread-5] com.wretchant.timer.OnBean               : destory
2019-09-01 22:13:10.272  INFO 111588 --- [       Thread-5] com.wretchant.timer.OnBean               : DisposableBean.destroy

执行顺序

  • @PreDestroy
  • DisposableBean.destroy

4、Spring 初始化 Bean 的源码

	/**
	 * 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(final String beanName, final 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);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}