美文网首页
Spring Bean的生命周期

Spring Bean的生命周期

作者: 坤坤坤坤杨 | 来源:发表于2022-12-06 10:29 被阅读0次

Spring在正常创建Bean的时候,实际上是调用了createBean方法中的doCreateBean方法。

createBean方法关键源码如下:
@Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
            。。。

        try {
            //让InstantiationAwareBeanPostProcessor有机会返回代理而不是目标bean实例
            //实际上就是调用:
            // applyBeanPostProcessorsBeforeInstantiation 内部for循环调用postProcessBeforeInstantiation 
            // applyBeanPostProcessorsAfterInitialization 内部for循环调用postProcessAfterInitialization
            // 上述两个具体的方法主要就是进行代理,实例化前和初始化后作一些增强性的操作,影响bean的创建流程
            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 {
            //spring正常利用构造器创建对象的流程
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isTraceEnabled()) {
                logger.trace("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
        。。。
    }
InstantiationAwareBeanPostProcessor使用场景

当不想使用spring默认创建bean的方法通过构造器创建bean,比如Mybatis的Mapper,它只有接口,没有实现类的构造方法,postProcessBeforeInstantiation就是在spring使用构造器帮你创建bean之前创建对象的,你可以创建一个代理对象返回,那么就可以实现自定义实例化对象了。

doCreateBean方法关键源码如下:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {

        。。。
        //这里开始对bean进行初始化
        Object exposedObject = bean;
        try {
            populateBean(beanName, mbd, instanceWrapper);// 对属性赋值
            exposedObject = initializeBean(beanName, exposedObject, mbd); // 对bean进行初始化
        }

        。。。
initializeBean方法关键源码如下:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        。。。
        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
          //  执行后置处理器 before
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            //执行用户自定义的 init 方法
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
           //  执行后置处理器 after 
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }
invokeInitMethods方法关键源码如下:
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
        throws Throwable {

    // 是否实现了 InitializingBean 接口
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        if (logger.isTraceEnabled()) {
            logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
        }
        if (System.getSecurityManager() != null) {
            try {
                AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                    ((InitializingBean) bean).afterPropertiesSet();
                    return null;
                }, getAccessControlContext());
            }
            catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        }
        else {
            // 直接调用 afterPropertiesSet()
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }

    if (mbd != null && bean.getClass() != NullBean.class) {
        // 判断是否指定了 init-method(),
        // 如果指定了 init-method(),则再调用制定的init-method
        String initMethodName = mbd.getInitMethodName();
        if (StringUtils.hasLength(initMethodName) &&
                !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                !mbd.isExternallyManagedInitMethod(initMethodName)) {
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}

相关文章

网友评论

      本文标题:Spring Bean的生命周期

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