spring bean工厂和工厂bean 源码分析

聊聊工厂bean和bean工厂有什么同异,先说结论

  • bean工厂:不是bean,在spring中一般指的是DefaultListableBeanFactory对象,管理和维护spring中所有的bean
  • 工厂bean:一种特殊的bean,在xml文件中配置的,用来生成新的bean的加工厂,通过getObject()方法可以获取其生产的新bean,如果想获取该工厂bean本身,需要使用类似于getBean("&" + beanName)的样式。

demo

先来个小demo,具体学习和了解下如何使用工厂bean

public class StudentFactoryBean extends AbstractFactoryBean<Object> {

    @Override
    public Class<?> getObjectType() {
        return Student.class;
    }

    @Override
    protected Object createInstance() throws Exception {
        return new Student("factoryDemo", 18);
    }

    @Override
    public String toString() {
        return "StudentFactoryBean";
    }
}

public class Bootstrap {

    public static void main(String[] args){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                new String[]{"context.xml"}, false);

        applicationContext.setAllowBeanDefinitionOverriding(false);
        applicationContext.refresh();

        Student student = (Student)applicationContext.getBean("studentFactory");
        // 生成工厂类生成的具体实体类,值的是studentFactory生成的类
        System.out.println(student.toString());

        StudentFactoryBean studentFactoryBean = (StudentFactoryBean) applicationContext.getBean("&studentFactory");
        // 名字加了一个& 获取的是studentFactory本身
        System.out.println(studentFactoryBean.toString());
    }
}
<bean name="studentFactory" class="com.demo.StudentFactoryBean" />

如上述代码所述,我们自定义继承了AbstractFactoryBean抽象类,并实现了几个方法,便于生成具体的Student类

image.png

执行结果也如设想的一般,分别打印各自对象的toString,不过className并没有被自动注解上

源码分析

以前的学习我们已经知道了在refresh已经完成了对xml配置的bean的实例化操作了。如下图当还未执行getBean("studentFactory")操作时,studentFactory和对应的实体类都已经完成了实例化操作(这点是需要关注的点)

image.png

接下来我们就在回过头看看refresh的操作是如何完成实例化的。

DefaultListableBeanFactory 文件

public void preInstantiateSingletons() throws BeansException {
    List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        // 得到合并parentBean的beandefinition bd
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
           // 不是抽象类 是单例类型同时不是懒加载的beandefinition
            if (isFactoryBean(beanName)) {
               // 如果是工厂bean(针对beanName对应的class类型匹配判断)
                final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                // 调用getBean("&" + beanName)操作,返回的factory是工厂bean实例
                // 这样在这个bean实例中,存储着映射的具体bean
                boolean isEagerInit;
                if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                    isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                        @Override
                        public Boolean run() {
                            return ((SmartFactoryBean<?>) factory).isEagerInit();
                        }
                    }, getAccessControlContext());
                }
                else {
                    isEagerInit = (factory instanceof SmartFactoryBean &&
                            ((SmartFactoryBean<?>) factory).isEagerInit());
                }
                if (isEagerInit) {
                    getBean(beanName);
                }
            }
            else {
                getBean(beanName);
            }
        }
    }

    // Trigger post-initialization callback for all applicable beans...
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged(new PrivilegedAction<Object>() {
                    @Override
                    public Object run() {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }
                }, getAccessControlContext());
            }
            else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}

AbstractBeanFactory 文件

protected <T> T doGetBean(
        final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
        throws BeansException {

    final String beanName = transformedBeanName(name);
    // 如果是"&" + beanName,那么beanName就是去掉&的值
    Object bean;

    Object sharedInstance = getSingleton(beanName);
    // 从singletonObjects 中获取已经处理好的single 实例化对象
    if (sharedInstance != null && args == null) {
        // single已经有数据了,而且参数也没有,生成真正的对象bean
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
        if (isPrototypeCurrentlyInCreation(beanName)) {
           // 如果当前的beanName在prototype的创建中,则抛出异常
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // 获取当前bean工厂的父亲工厂
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // 如果有父亲工厂,而且还未处理
            String nameToLookup = originalBeanName(name);
            if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
        }

        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
        }

        try {
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // 得到当前beandefinition的依赖元素
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    if (isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    registerDependentBean(dep, beanName);
                    getBean(dep);
                        // 把每一个必须依赖的bean注册好,并进行实例化操作
                }
            }

            // 到这里就完成了一个对象实例化之前的操作了,现在需要创建具体的对象
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                    @Override
                    public Object getObject() throws BeansException {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            destroySingleton(beanName);
                            throw ex;
                        }
                    }
                });
                // 得到的sharedInstance 是工厂类 StudentBeanFactory对象
                // 获取真正的实例对象,返回
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }

            else if (mbd.isPrototype()) {
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                }
                finally {
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }

            else {
                String scopeName = mbd.getScope();
                final Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }
                try {
                    Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                        @Override
                        public Object getObject() throws BeansException {
                            beforePrototypeCreation(beanName);
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            finally {
                                afterPrototypeCreation(beanName);
                            }
                        }
                    });
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                }
                catch (IllegalStateException ex) {
                    throw new BeanCreationException(beanName,
                            "Scope '" + scopeName + "' is not active for the current thread; consider " +
                            "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                            ex);
                }
            }
        }
        catch (BeansException ex) {
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }

    // Check if required type matches the type of the actual bean instance.
    if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
        try {
            return getTypeConverter().convertIfNecessary(bean, requiredType);
        }
        catch (TypeMismatchException ex) {
            if (logger.isDebugEnabled()) {
                logger.debug("Failed to convert bean '" + name + "' to required type '" +
                        ClassUtils.getQualifiedName(requiredType) + "'", ex);
            }
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    // 强转类型为T
    return (T) bean;
}

AbstractAutowireCapableBeanFactory 文件 真正创建对象的方法

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
        throws BeanCreationException {

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
    Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
    mbd.resolvedTargetType = beanType;

    // 获取到所有的MergedBeanDefinitionPostProcessor 对象,依次去修改对应的bean信息
    // 这样就可以再对BeanDefinition 进行修改处理了
    // 而且!!!自动注入值就是在这里通过AutowiredAnnotationBeanPostProcessor类完成的
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
        }
    }

    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
    // 判断是否是正在处理当前这个single对象,而且允许循环引用
    if (earlySingletonExposure) {
        if (logger.isDebugEnabled()) {
            logger.debug("Eagerly caching bean '" + beanName +
                    "' to allow for resolving potential circular references");
        }
        addSingletonFactory(beanName, new ObjectFactory<Object>() {
            @Override
            public Object getObject() throws BeansException {
                return getEarlyBeanReference(beanName, mbd, bean);
            }
        });
    }

    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
        populateBean(beanName, mbd, instanceWrapper);
        // 完成值的真正填充,注意在上面说过使用AutowiredAnnotationBeanPostProcessor注入值,其实并没有注入绝对的值,而是注入的相关数据,在populated的时候才是完成真正的值注入
        if (exposedObject != null) {
            exposedObject = initializeBean(beanName, exposedObject, mbd);
            // 这一步很关键,重点关注下面贴出来的invokeInitMethods 方法
        }
    }
    catch (Throwable ex) {
        if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
            throw (BeanCreationException) ex;
        }
        else {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
        }
    }
   ....
    return exposedObject;
}

//   ======  分割线 ======

protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
        throws Throwable {

    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        if (logger.isDebugEnabled()) {
            logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
        }
        if (System.getSecurityManager() != null) {
            try {
                AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                    @Override
                    public Object run() throws Exception {
                        ((InitializingBean) bean).afterPropertiesSet();
                        return null;
                    }
                }, getAccessControlContext());
            }
            catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        }
        else {
           // 调用afterPropertiesSet 方法,完成对bean的singletonInstance实例化
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }
  ...
}

AbstractFactoryBean 文件

    public void afterPropertiesSet() throws Exception {
        if (isSingleton()) {
            this.initialized = true;
            this.singletonInstance = createInstance();
            // 相当关键的一步!!!!!调用createInstance
            this.earlySingletonInstance = null;
        }
    }

如图所示,在执行initializeBean之前时,完成了对象的实例化,还会继续进行初始化bean操作

image.png

执行initializeBean 之后,已经填充了singletonInstance 对象了,其包含的是工厂生成的bean数据

image.png

完成整个的refresh操作之后,其实所有的未懒加载的bean都已经完成的实例化,工厂bean对应的具体bean也被保存在工厂bean中。

接下来讲讲在完成实例化之后,调用getBean获取工厂bean实例以及工厂bean本身的细节

  • getBean("studentFactory")
  • getBean("&studentFactory")

1、老套路来到了doGetBean方法,得出name的原始beanName值
2、从singletonObjects找确认存在该值
3、进入到getObjectForBeanInstance方法
4、如果想要返回的是工厂bean本身,而且还不为null,直接返回(也就是getBean("&studentFactory")操作)
5、从factoryBeanObjectCache确认是否存在对应的值

如果有,意味着存在这个对应的值,直接返回(也就是多次getBean("studentFactory")操作)
没有,需要getObjectFromFactoryBean这个方法,往factoryBeanObjectCache填充新的实例

image.png

这里需要注意的是存储的value是工厂bean关联的真实bean直接返回(也就是首次执行getBean("studentFactory")操作)

不过最后还有个问题,就是最后生成的该对象Student并没有为className注入值,通过上面的实现,压根没有自动注解的那段操作,而是在自定义的工厂bean中通过createInstance方法返回的,所以肯定是没有值的。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容