zoukankan      html  css  js  c++  java
  • 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);
            }

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

  • 相关阅读:
    织梦开发——相关阅读likeart应用
    织梦标签教程
    织梦专题调用代码
    HIT 2543 Stone IV
    POJ 3680 Intervals
    HIT 2739 The Chinese Postman Problem
    POJ 1273 Drainage Ditches
    POJ 2455 Secret Milking Machine
    SPOJ 371 Boxes
    HIT 2715 Matrix3
  • 原文地址:https://www.cnblogs.com/houzheng/p/11885278.html
Copyright © 2011-2022 走看看