Spring源码:Bean初始化过程

      • 主代码
        • 1. 激活Aware方法
        • 2. 后处理方法(初始化之前调用)
        • 3. 激活自定义的init方法
        • 4. 后处理方法(初始化之后调用)

主代码

bean完成属性注入之后,接着要以bean进行初始化,初始化过程在AbstractAutowireCapableBeanFactory抽象类中,核心代码如下:

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    // 激活Aware方法
    invokeAwareMethods(beanName, bean);

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 若mbd为null或者mbd不是合成的,执行BeanPostProcessor扩展点的PostProcessBeforeInitialization进行修改实例化Bean
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
    /* 调用Bean的初始化方法,这个初始化方法是在BeanDefinition中通过定义init-method属性指定的。
    ** 同时,如果Bean实现了InitializingBean接口,那么这个Bean的afterPropertiesSet实现也会
    ** 被调用
    */
    invokeInitMethods(beanName, wrappedBean, mbd);

    if (mbd == null || !mbd.isSynthetic()) {
        // 执行BeanPostProcessor扩展点的PostProcessAfterInitialization进行修改实例化Bean
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    return wrappedBean;
}

1. 激活Aware方法

核心代码:

private void invokeAwareMethods(final String beanName, final Object bean) {
    if (bean instanceof Aware) {
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName);
        }
        if (bean instanceof BeanClassLoaderAware) {
            ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
        }
        if (bean instanceof BeanFactoryAware) {
         ((BeanFactoryAware)bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}
  • BeanNameAware:让Bean获取自己在BeanFactory配置中的名字(根据情况是id或者name)

    Spring自动调用。并且会在Spring自身完成Bean配置之后,且在调用任何Bean生命周期回调(初始化或者销毁)方法之前就调用这个方法。换言之,在程序中使用BeanFactory.getBean(String beanName)之前,Bean的名字就已经设定好了。

  • BeanClassLoaderAware: 获取Bean的类装载器

  • BeanFactoryAware:让Bean获取配置他们的BeanFactory的引用

    >

    setBeanFactory方法是在根据某个配置文件创建了一个新工厂之后,Spring才调用这个方法,并把BeanFactory注入到Bean中。 让bean获取配置自己的工厂之后,可以在Bean中使用这个工厂的getBean()方法,但是,实际上非常不推荐这样做,因为结果是进一步加大Bean与Spring的耦合,而且,能通过DI注入进来的尽量通过DI来注入。

2. 后处理方法(初始化之前调用)

3. 激活自定义的init方法

protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        // 实现了InitializingBean接口 && (mbd为null || mbd中的afterPropertiesSet方法不是外部方法)
        ((InitializingBean) bean).afterPropertiesSet();
    }

    if (mbd != null) {
        String initMethodName = mbd.getInitMethodName();
        if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) {
            // 调用自定义的初始化方法
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}   

自定义初始化方法(在配置文件指定init-method)

protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
    // 获取初始化方法名称
    String initMethodName = mbd.getInitMethodName();
    final Method initMethod = (mbd.isNonPublicAccessAllowed() ?
                               BeanUtils.findMethod(bean.getClass(), initMethodName) :
                               ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));

    if (initMethod == null) {
        if (mbd.isEnforceInitMethod()) {
            // 若指示配置的init方法是是默认方法,且不存在,抛出异常找不到该方法
            throw new BeanDefinitionValidationException(".....");
        } else {
            // 没有找到默认的名字叫initMethodName初始化的初始化方法
            return;
        }
    }

    ReflectionUtils.makeAccessible(initMethod);
    initMethod.invoke(bean);
}

4. 后处理方法(初始化之后调用)

你可能感兴趣的:(spring)