• 一次性讲清楚spring中bean的生命周期之三:bean是如何实例化的


    在前面的两篇博文《一次性讲清楚spring中bean的生命周期之一:getSingleton方法》和《一次性讲清楚spring中bean的生命周期之二:FactoryBean的前世今生》中分析了spring中bean生命周期的过程中的getSingleton方法和getObjectForBeanInstance方法,今天来分析另外一个重要的方法createBean方法。分析的入口是AbstractBeanFacotry.doGetBean方法,如下图,

    这就是本次分析的入口。下面看该方法的详细定义,AbstractAutowireCapableBeanFactory.createBean

    @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);
            }
    
            // Prepare method overrides.
            try {
                mbdToUse.prepareMethodOverrides();
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                        beanName, "Validation of method overrides failed", ex);
            }
    
            try {
                // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
    //给beanPostProcessor一个返回目标类代理类的机会 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 {
    //执行doCreatBean方法 Object beanInstance
    = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }

    重点部分已用红色标出,下面具体来分析

    bean生命周期前

    在上面的方法定义中有这样一段代码,

    // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
                Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

    就是说在进入bean的创建之前,开发者可以自己返回一个目标类的代理类,如果返回了那么便直接返回,不会继续向下执行。看该方法怎么实现的,AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation

    @Nullable
        protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
            Object bean = null;
            if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
                // Make sure bean class is actually resolved at this point.
                if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                    Class<?> targetType = determineTargetType(beanName, mbd);
                    if (targetType != null) {
    //应用BeanPostProcessor实例化前 bean
    = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) {
    //应用BeanpPostProcessor初始化后 bean
    = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }

    该方法重要的就是applyBeanPostProcessorsBeforeInstantiation和applyBeanPostProcessorsAfterInitalization方法。

    applyBeanPostProcessorsBeforeInstantiation

    @Nullable
        protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
    //在spring中有InstantiationAwareBeanPostProcessor的实例,则执行其postProcessBeforeInstantiation方法
    if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }

    该方法的主要作用是如果在spring中有InstantiationAwareBeanPostProcessor类型的beanPostProcessor的化,会执行其postProcessBeforeInstantiation方法,也就是我们可以实现InstantiationAwareBeanPostProcessor接口,并实现其postProcessBeforeInstantiation方法。默认情况下该接口的方法返回null,

    @Nullable
        default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            return null;
        }

    applyBeanPostProcessorsAfterInitalization

    回过头来看另外一个方法,

    @Override
        public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
                throws BeansException {
    
            Object result = existingBean;
    //遍历spring容器中所有的beanPostProcessor,执行其postProcessAfterInitialization方法
    for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }

    BeanPostProcessor接口中该方法默认返回如下

    @Nullable
        default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }

    在spring容器中会有多少BeanPostProcessor这个后面会分析。

    分析完了进入bean生命周期前的方法,也就是留个开发者一个后门,通过实现InstantiationAwareBeanPostProcessor接口中的postProcessBeforeInstantiation方法可以自定义返回一个目标类型的代理对象。现在回到createBean方法中,真正进入bean的生命周期,看doCreateBean方法,

    doCreateBean

    该方法的篇幅过长,仅保留关键代码,其他代码删除,请知悉,

    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 instanceWrapper
    = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } .... // 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"); }
    //放到singletonFactory中解决循环依赖的问题 addSingletonFactory(beanName, ()
    -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try {
    //属性注入 populateBean(beanName, mbd, instanceWrapper);
    //初始化bean exposedObject
    = initializeBean(beanName, exposedObject, mbd); } 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; }

     看createBeanInstance方法

    createBeanInstance

    该方法的定义如下,

    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
            // Make sure bean class is actually resolved at this point.
            Class<?> beanClass = resolveBeanClass(mbd, beanName);
    
            if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
            }
    
            Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
            if (instanceSupplier != null) {
                return obtainFromSupplier(instanceSupplier, beanName);
            }
            //使用实例工厂或静态工厂的方式生成bean实例
            if (mbd.getFactoryMethodName() != null) {
                return instantiateUsingFactoryMethod(beanName, mbd, args);
            }
    
            // Shortcut when re-creating the same bean...
            boolean resolved = false;
            boolean autowireNecessary = false;
            if (args == null) {
                synchronized (mbd.constructorArgumentLock) {
                    if (mbd.resolvedConstructorOrFactoryMethod != null) {
                        resolved = true;
                        autowireNecessary = mbd.constructorArgumentsResolved;
                    }
                }
            }
            if (resolved) {
                if (autowireNecessary) {
                    return autowireConstructor(beanName, mbd, null, null);
                }
                else {
                    return instantiateBean(beanName, mbd);
                }
            }
    
            // Candidate constructors for autowiring?
    //检测是否有重写的构造方法 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } // Preferred constructors for default construction?
    //首选默认的构造方法 ctors = mbd.getPreferredConstructors(); if (ctors != null) { return autowireConstructor(beanName, mbd, ctors, null); } // No special handling: simply use no-arg constructor.
    //使用无参构造方法 return instantiateBean(beanName, mbd); }

    从上面的方法中可以看出实例化bean,其实就是使用类的构造方法来进行实例化,这里看下instantiateBean方法的过程,

    instantiateBean

    看该方法的定义,

    protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
            try {
                Object beanInstance;
                final BeanFactory parent = this;
                if (System.getSecurityManager() != null) {
                    beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
                            getInstantiationStrategy().instantiate(mbd, beanName, parent),
                            getAccessControlContext());
                }
                else {
    //生成bean的实例 beanInstance
    = getInstantiationStrategy().instantiate(mbd, beanName, parent); }
    //构造一个beanWrapper对象 BeanWrapper bw
    = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; } catch (Throwable ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); } }

    从上面的代码可以看到该方法中重要的就是下面这句

    beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);

    看下getInstantiationStrategy()方法返回什么,

    /**
         * Return the instantiation strategy to use for creating bean instances.
         */
        protected InstantiationStrategy getInstantiationStrategy() {
            return this.instantiationStrategy;
        }

    返回的是一个属性,

    /** Strategy for creating bean instances. */
        private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();

    是一个CglibSubclassingInstantiationStragegy对象,看其instantiate方法,由于CglibSubclassingInstantiationStrategy继承了SimpleInstantiationStrategy类,该方法在父类SimpleInstantiationStrategy中

    @Override
        public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
            // Don't override the class with CGLIB if no overrides.
    //如果没有使用lookup或replaced,不使用CGLIB重写该类 if (!bd.hasMethodOverrides()) { Constructor<?> constructorToUse; synchronized (bd.constructorArgumentLock) { constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod; if (constructorToUse == null) { final Class<?> clazz = bd.getBeanClass(); if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface"); } try { if (System.getSecurityManager() != null) { constructorToUse = AccessController.doPrivileged( (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor); } else { constructorToUse = clazz.getDeclaredConstructor(); } bd.resolvedConstructorOrFactoryMethod = constructorToUse; } catch (Throwable ex) { throw new BeanInstantiationException(clazz, "No default constructor found", ex); } } } return BeanUtils.instantiateClass(constructorToUse); } else { // Must generate CGLIB subclass.
    //使用cglib生成子类 return instantiateWithMethodInjection(bd, beanName, owner); } }

    从上面可以看出有两种方式生成实例,使用反射的机制

    return BeanUtils.instantiateClass(constructorToUse);

    如果有lookup或replaced,使用cglib方式

    return instantiateWithMethodInjection(bd, beanName, owner);

    BeanUtils.instantiateClass(反射)

    public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
            Assert.notNull(ctor, "Constructor must not be null");
            try {
                ReflectionUtils.makeAccessible(ctor);
                return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
                        KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
            }
            catch (InstantiationException ex) {
                throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
            }
            catch (IllegalAccessException ex) {
                throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
            }
            catch (IllegalArgumentException ex) {
                throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
            }
            catch (InvocationTargetException ex) {
                throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
            }
        }

    标红的代码就是生成的逻辑,可以看到是利用的java的反射机制,也就是使用Constructor类的newInstance方法。

    instantiateWithMethodInjection(cglib)

    该方法在CglibSubclassingInstantiationStrategy中

    @Override
        protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
            return instantiateWithMethodInjection(bd, beanName, owner, null);
        }
    @Override
        protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
                @Nullable Constructor<?> ctor, Object... args) {
    
            // Must generate CGLIB subclass...
            return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
        }

    使用的是CglibSubclassCreator生成的实例,具体方式就是cglib生成代理类的方式,

    public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
                Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
                Object instance;
                if (ctor == null) {
                    instance = BeanUtils.instantiateClass(subclass);
                }
                else {
                    try {
                        Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
                        instance = enhancedSubclassConstructor.newInstance(args);
                    }
                    catch (Exception ex) {
                        throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
                                "Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
                    }
                }
                // SPR-10785: set callbacks directly on the instance instead of in the
                // enhanced class (via the Enhancer) in order to avoid memory leaks.
                Factory factory = (Factory) instance;
                factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
                        new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
                        new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
                return instance;
            }

    分析完毕spring中单例bean的实例化过程。

    总结

    至此分析完了spring中单例bean的实例化过程,主要有两点,

    1、类中有lookup或replaced方式,使用cglib的方式生成bean的实例;

    2、类中无lookup或replaced方式,使用java反射机制Constructor生成实例;

    推荐阅读

    一次性讲清楚spring中bean的生命周期之二:FactoryBean的前世今生 》

    一次性讲清楚spring中bean的生命周期之一:getSingleton方法

    一个爱写文章的程序员,欢迎关注我的公众号“北漂程序员”。我有故事,你有酒吗
  • 相关阅读:
    【小白学PyTorch】1 搭建一个超简单的网络
    【小白学PyTorch】2 浅谈训练集和测试集
    【小白学AI】GBDT梯度提升详解
    【小白学AI】XGBoost推导详解与牛顿法
    【小白写论文】技术性论文结构剖析
    小白学PyTorch 动态图与静态图的浅显理解
    【小白学推荐1】 协同过滤 零基础到入门
    【小白学AI】随机森林 全解 (从bagging到variance)
    OpenCV开发笔记(七十二):红胖子8分钟带你使用opencv+dnn+tensorFlow识别物体
    【python刷题】二叉搜索树-相关题目
  • 原文地址:https://www.cnblogs.com/teach/p/15008367.html
Copyright © 2020-2023  润新知