从Bean的实例中获取对象

在getBean的方法中,getObjectForBeanInstance是使用频率很高的方法。我们得到bean的之后要做的第一步就是来检测一下正确性,其实就是用于检测当前bean是不是FactoryBean类型的Bean,如果是,那么需要调用该bean对应的FactoryBean实例中的getObject作为返回值。

无论是从缓存中还是通过不同的scope策略加载的bean都只是原始的bean状态,并不一定是我们最终想要的bean。举个例子,加入我们需要对工厂bean进行处理,那么这里得到的其实就是工厂bean的初始状态,但是我们真正想要的是工厂bean中定义的Factory-method方法返回的bean实例,而getObjectForBeanInstance方法就是完成这个工作的。

protected Object getObjectForBeanInstance(
        Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
    // 如果指定的bean是工厂相关(以&作为前缀),且beanInstance又不是FactoryBean类型,则验证不通过
    if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
        throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
    }

    // 现在我们有了bean实例,这个实例可能是一个正常的bean或者是FactoryBean。
    // 如果是FactoryBean,我们使用它来创建一个bean实例,但是如果用户想要直接获取工厂实例而不是工厂的getObject方法
    // 对应的实例那么传入的name应该加前缀&
    if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
        return beanInstance;
    }

    // 加载FactoryBean
    Object object = null;
    if (mbd == null) {
        // 如果父标签不存在,先从缓存取
        object = getCachedObjectForFactoryBean(beanName);
    }
    if (object == null) {
        // Return bean instance from factory.
        // 到这里明确知道beanInstance一定是FactoryBean
        FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
        // Caches object obtained from FactoryBean if it is a singleton.
        // containsBeanDefinition检测beanDefinitionMap中也就是在所有已经加载的类中检测是否定义了beanName。
        if (mbd == null && containsBeanDefinition(beanName)) {
            // 将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition,
            // 如果指定BeanName是子Bean的话,同时合并父类的相关属性
            mbd = getMergedLocalBeanDefinition(beanName);
        }
        // 是否用户定义的而非程序本身定义的
        boolean synthetic = (mbd != null && mbd.isSynthetic());
        object = getObjectFromFactoryBean(factory, beanName, !synthetic);
    }
    return object;
}

从代码看,这个方法没有什么实质内容,都是一些辅助性的功能判断,真正核心的代码委托给了getObjectFromFactoryBean。我们看一下getObjectForBeanInstance的处理过程:

  1. 对FactoryBean的正确性做出验证
  2. 对非FactoryBean不做处理
  3. 对bean进行转换
  4. 将从Factory中解析bean的工作委托给getObjectFromFactoryBean。我们看一下getObjectFromFactoryBean的代码。

这个方法getObjectFromFactoryBean也没有什么,就是判断bean是不是单例,如果是保证全局的唯一性,做缓存。当然创建的时候都是调用doGetObjectFromFactoryBean方法。

是的在这个doGetObjectFromFactoryBean方法中最终还是使用FactoryBean#getObject方法。

调用getObjectFromFactoryBean方法之后它没有直接返回,而是做了一些后续处理。

我们进入AbstractAutowireCapableBeanFactory#postProcessObjectFromFactoryBean方法。

对于这个方法的实现他是与注解相关,这里不再多说,看到再说吧!这里我们只需要了解在Spring获取bean的规则中有这样一条:尽可能保证所有bean初始化后都会调用注册的BeanPostProcessor的postProcessAfterInitialization方法进行处理,在实际开发中大可以针对此特性设计自己的业务逻辑。

results matching ""

    No results matching ""