美文网首页Spring 学习笔记Spring注解
spring bean工厂和工厂bean 源码分析

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

作者: jwfy | 来源:发表于2018-01-30 19:30 被阅读234次

    聊聊工厂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方法返回的,所以肯定是没有值的。

    相关文章

      网友评论

        本文标题:spring bean工厂和工厂bean 源码分析

        本文链接:https://www.haomeiwen.com/subject/nbthzxtx.html