• springIOC源码接口分析(八):AutowireCapableBeanFactory


    参考博文: https://blog.csdn.net/f641385712/article/details/88651128

    一 接口规范

    从宏观上看,AutowireCapableBeanFactory提供了如下能力:

     1 为已经实例化的对象装配属性,这些属性对象都是Spring管理的;

     2 实例化一个Bean,并自动装配,这些被装配的属性对象都是Spring管理的,但是实例化的Bean可以不被Spring管理(这点特别重要)。所以这个接口提供功能就是自动装配bean相关的

      (自动装配的原对象可以不在Spring的IOC容器里,但是需要被依赖注入的成员,就必须是Spring容器管辖的Bean)
     此接口主要是针对框架之外,没有向Spring托管Bean的应用。通过暴露此功能,Spring框架之外的程序,也能具有自动装配的能力(此接口赋予它的)。

     可以使用这个接口集成其它框架。捆绑并填充(注入)并不由Spring管理生命周期并已存在的实例.像集成WebWork的Actions 和Tapestry Page就很实用
     一般应用开发者不会使用这个接口,所以像ApplicationContext这样的外观实现类不会实现这个接口,

     但是提供了getAutowireCapableBeanFactory()方法允许你拿这个工具去做你需要的事。

    接口定义:

    public interface AutowireCapableBeanFactory01 extends BeanFactory {
        /**
         * 表明工厂没有自动装配的Bean
         */
        int AUTOWIRE_NO = 0;
    
        /**
         * 表明根据名称自动装配
         */
        int AUTOWIRE_BY_NAME = 1;
    
        /**
         * 表明根据类型自动装配
         */
        int AUTOWIRE_BY_TYPE = 2;
    
        /**
         * 表明根据构造方法快速装配
         */
        int AUTOWIRE_CONSTRUCTOR = 3;
    
        @Deprecated
        // 表明通过Bean的class的内部来自动装配 Spring3.0被弃用。
        int AUTOWIRE_AUTODETECT = 4;
    
        String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";
    
        /**
         * 创建一个指定class的实例
         */
        <T> T createBean(Class<T> beanClass) throws BeansException;
    
        /**
         * 通过调用给定Bean的after-instantiation及post-processing接口,对bean进行配置
         */
        void autowireBean(Object existingBean) throws BeansException;
    
        /**
         * 自动装配属性,填充属性值,使用诸如setBeanName,setBeanFactory这样的工厂回调填充属性,最好还要调用post processor
         */
        Object configureBean(Object existingBean, String beanName) throws BeansException;
    
        /**
         * 创建一个指定class的实例,通过参数可以指定其自动装配模式(by-name or by-type).
         */
        Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
    
        /**
         * 通过指定的自动装配策略来初始化一个Bean
         */
        Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
    
        /**
         * 通过指定的自动装配方式来对给定的Bean进行自动装配
         */
        void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
                throws BeansException;
    
        /**
         * 将参数中指定了那么的Bean,注入给定实例当中
         */
        void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
    
        /**
         * 初始化参数中指定的Bean,调用任何其注册的回调函数如setBeanName、setBeanFactory等。
         */
        Object initializeBean(Object existingBean, String beanName) throws BeansException;
    
        /**
         * 调用参数中指定Bean的postProcessBeforeInitialization方法
         */
        Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
                throws BeansException;
    
        /**
         * 调用参数中指定Bean的postProcessAfterInitialization方法
         */
        Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
                throws BeansException;
    
        /**
         * 销毁参数中指定的Bean,同时调用此Bean上的DisposableBean和DestructionAwareBeanPostProcessors方法
         */
        void destroyBean(Object existingBean);
    
        /**
         * 查找唯一符合指定类的实例,如果有,则返回实例的名字和实例本身
         * 底层依赖于:BeanFactory中的getBean(Class)方法
         */
        <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
    
        /**
         * 解析出在Factory中与指定Bean有指定依赖关系的Bean(@Autowired依赖注入的核心方法)
         */
        Object resolveBeanByName(String name, DependencyDescriptor descriptor) throws BeansException;
    
        @Nullable
        Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;
    
        @Nullable
        Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
                                 @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
    }

    二 实际应用

     准备一个外部类,即不被spring容器管理:

    public class Person {
    
        //不使用@Autowired
        private User user;
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    }

    spring管理的User bean进行实例化,这里以spring-bean.xml为例:

     利用AutowireCapableBeanFactory创建Bean:

    public class BeanTest{
        @Test
        public void beanTest(){
            ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean.xml");
            //ApplicationContext没有实现接口,但是可以通过方法直接获取使用
            AutowireCapableBeanFactory autowireCapableBeanFactory = applicationContext.getAutowireCapableBeanFactory();
            // autowireCapableBeanFactory创建Bean实例,执行多次就创建多个
            Person person = (Person) autowireCapableBeanFactory.createBean(Person.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
            //没有@Autowired注解也直接给注入了
            System.out.println("获取自动注入的属性:"+person.getUser());
            //异常: No qualifying bean of type 'com.hou.spring.Person' available
            Person bean = applicationContext.getBean(Person.class);//没有交给spring容器管理
            System.out.println(bean);
        }
    }

    执行结果:

    不使用接口测试:

    三 源码分析

    主要从createBean方法进行分析:

    这个接口调用的方法是在AbstractAutowireCapableBeanFactory抽象类中实现的:

        @Override
        public Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
            // Use non-singleton bean definition, to avoid registering bean as dependent bean.
            RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
            //这里设置为原型,而不是单例,所以调用多次会生成多个对象
            bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
            return createBean(beanClass.getName(), bd, null);
        }

    然后就是return里面调用的createBean方法,这个是AbstractAutowireCapableBeanFactory类的父类AbstractBeanFactory定义的抽象方法:

     AbstractAutowireCapableBeanFactory类中实现了这个抽象方法,这个方法很单纯:创建一个实例,然后初始化他(给属性们赋值),然后return出去即可:

        @Override
        protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                throws BeanCreationException {
    
            if (logger.isTraceEnabled()) {
                logger.trace("Creating instance of bean '" + beanName + "'");
            }
            RootBeanDefinition mbdToUse = mbd;
    
            // Make sure bean class is actually resolved at this point, and
            // clone the bean definition in case of a dynamically resolved Class
            // which cannot be stored in the shared merged bean definition.
            Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
            if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
                mbdToUse = new RootBeanDefinition(mbd);
                mbdToUse.setBeanClass(resolvedClass);
            }
            
            try {
                mbdToUse.prepareMethodOverrides();
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                        beanName, "Validation of method overrides failed", ex);
            }
    
            try {
                //若BeanPostProcessors 产生了一个代理对象,就不需要我去创建了,就不继续往下走了(AOP都走这里)
                Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
                if (bean != null) {
                    return bean;
                }
            }
            catch (Throwable ex) {
                throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                        "BeanPostProcessor before instantiation of bean failed", ex);
            }
    
            try {
                //本类的一个protected方法,专门用于处理创建Bean的过程(包括属性赋值之类的)
                Object beanInstance = doCreateBean(beanName, mbdToUse, args);
                if (logger.isTraceEnabled()) {
                    logger.trace("Finished creating instance of bean '" + beanName + "'");
                }
                return beanInstance;
            }
            catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
                throw ex;
            }
            catch (Throwable ex) {
                throw new BeanCreationException(
                        mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
            }
        }

    再看本类的doCreateBean方法,主要有三个核心步骤三个步骤:createBeanInstancepopulateBeaninitializeBean:

        protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
                throws BeanCreationException {
    
            // Instantiate the bean.
            BeanWrapper instanceWrapper = null;
            if (mbd.isSingleton()) {
                instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
            }
            if (instanceWrapper == null) {
                //创建Bean实例,返回一个BeanWrapper,它也是本类的一个protected方法
                instanceWrapper = createBeanInstance(beanName, mbd, args);
            }
            final Object bean = instanceWrapper.getWrappedInstance();
            Class<?> beanType = instanceWrapper.getWrappedClass();
            if (beanType != NullBean.class) {
                mbd.resolvedTargetType = beanType;
            }
    
            // 处理循环引用,现在若我们Bean不在容器里,肯定是不存在循环引用的(但是我依赖的Bean可能还没创建是真的,也是这里来处理的)
            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;
                }
            }
    
            // Eagerly cache singletons to be able to resolve circular references
            // even when triggered by lifecycle interfaces like BeanFactoryAware.
            boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                    isSingletonCurrentlyInCreation(beanName));
            if (earlySingletonExposure) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Eagerly caching bean '" + beanName +
                            "' to allow for resolving potential circular references");
                }
                addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
            }
    
    
            Object exposedObject = bean;
            try {
                //// 给Bean实例的各个属性进行赋值
                populateBean(beanName, mbd, instanceWrapper);
                //初始化Bean 执行一些初始化方法init @PostContruct方法等等
                exposedObject = initializeBean(beanName, exposedObject, mbd);
            }

    其他具体细节以后其他博文专门记录笔记

  • 相关阅读:
    codeforces 349B Color the Fence 贪心,思维
    luogu_2022 有趣的数
    luogu_2320 [HNOI2006]鬼谷子的钱袋
    luogu_1879 [USACO06NOV]玉米田Corn Fields
    SAC E#1
    luogu_1984 [SDOI2008]烧水问题
    luogu_2085 最小函数值
    luogu_1631 序列合并
    luogu_1196 银河英雄传说
    luogu_1037 产生数
  • 原文地址:https://www.cnblogs.com/houzheng/p/11885278.html
Copyright © 2020-2023  润新知