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

Spring源码:Bean初始化过程

程序员文章站 2022-05-21 23:05:28
...

主代码

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. 后处理方法(初始化之后调用)