Spring IOC:bean的生命周期与@Autowire(3)

全系列文章:

《Spring IOC:bean的生命周期与@Autowire(1)》

《Spring IOC:bean的生命周期与@Autowire(2)》

《Spring IOC:bean的生命周期与@Autowire(3)》​​​​​​​

目录

一、AbstractAutowireCapableBeanFactory#initializeBean

二、invokeAwareMethods

三、applyBeanPostProcessorsBeforeInitialization

四、invokeInitMethods

五、applyBeanPostProcessorsAfterInitialization


写在开头:本文为学习后的总结,可能有不到位的地方,错误的地方,欢迎各位指正。

        前文中我们走完了bean的实例化与属性注入的流程,本文中我们继续走完后续的流程。

一、AbstractAutowireCapableBeanFactory#initializeBean

        doCreateBean的最后一步,bean的初始化流程,调用initializeBean方法完成。

​
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
        throws BeanCreationException {
 
    // 1、实例化bean
    instanceWrapper = createBeanInstance(beanName, mbd, args);
 
    // 2、应用后置处理器MergedBeanDefinitionPostProcessor,允许修改MergedBeanDefinition
    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
 
    // 3、创建三层缓存,为避免循环依赖做准备
	addSingletonFactory(beanName, new ObjectFactory<Object>() {
		@Override
		public Object getObject() throws BeansException {
			return getEarlyBeanReference(beanName, mbd, bean);
		}
	});
 
    // 4、属性注入
    populateBean(beanName, mbd, instanceWrapper);
 
    // 5、初始化bean
	exposedObject = initializeBean(beanName, exposedObject, mbd);

    // ...
}
 
​

         initializeBean方法中,将会完成bean创建的所有剩余操作。包括invokeAwareMethods、applyBeanPostProcessorsBeforeInitialization、invokeInitMethods、applyBeanPostProcessorsAfterInitialization这几个步骤。

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    // 1.激活Aware方法
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
                invokeAwareMethods(beanName, bean);
                return null;
            }
        }, getAccessControlContext());
    } else {
        invokeAwareMethods(beanName, bean);
    }
 
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 2.在初始化前应用BeanPostProcessor的postProcessBeforeInitialization方法,允许对bean实例进行包装
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
 
    try {
        // 3.调用初始化方法
        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()) {
        // 4.在初始化后应用BeanPostProcessor的postProcessAfterInitialization方法,允许对bean实例进行包装
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    // 5.返回wrappedBean
    return wrappedBean;
}

二、invokeAwareMethods

        invokeAwareMethods方法会判断当前正在创建的bean是否实现了Aware的一些子类接口,如果继承了,将会依次调用当前bean的重写了的方法,包括setBeanName、setBeanClassLoader、setBeanFactory等方法。需要注意的是,这个步骤是由bean控制的,而非Spring容器。

private void invokeAwareMethods(final String beanName, final Object bean) {
    if (bean instanceof Aware) {
        // BeanNameAware: 实现此接口的类想要拿到beanName,因此我们在这边赋值给它
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName);
        }
        // BeanClassLoaderAware:实现此接口的类想要拿到beanClassLoader,因此我们在这边赋值给它
        if (bean instanceof BeanClassLoaderAware) {
            ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
        }
        // BeanFactoryAware: 实现此接口的类想要拿到 BeanFactory,因此我们在这边赋值给它
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}

三、applyBeanPostProcessorsBeforeInitialization

        在调用完bean继承的aware接口的重写方法后,调用所有 BeanPostProcessors 的 postProcessBeforeInitialization 方法。

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
        throws BeansException {
 
    Object result = existingBean;
    // 1.遍历所有注册的BeanPostProcessor实现类,调用postProcessBeforeInitialization方法
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
        // 2.在bean初始化方法执行前,调用postProcessBeforeInitialization方法
        result = beanProcessor.postProcessBeforeInitialization(result, beanName);
        if (result == null) {
            return result;
        }
    }
    return result;
}

         这里有一个重要的实现类ApplicationContextAwareProcessor用于获取当前的应用上下文,属于Spring内置的后置处理器,当调用到这个类的时候,会去判断当前bean是否实现了一些aware接口,如果继承了,则需要依次调用相应的重写方法,比如setApplicationContext。

// AbstractApplicationContext.java
// 在refresh方法中提前注册的内置后置处理器
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // ...
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
}

// ApplicationContextAwareProcessor.java
@Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
    AccessControlContext acc = null;
 
    if (System.getSecurityManager() != null &&
            (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
                    bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
                    bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
        acc = this.applicationContext.getBeanFactory().getAccessControlContext();
    }
 
    if (acc != null) {
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
                invokeAwareInterfaces(bean);
                return null;
            }
        }, acc);
    }
    else {
        // 调用Aware接口
        invokeAwareInterfaces(bean);
    }
 
    return bean;
}
 
private void invokeAwareInterfaces(Object bean) {
    if (bean instanceof Aware) {
        if (bean instanceof EnvironmentAware) {
            ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
        }
        if (bean instanceof EmbeddedValueResolverAware) {
            ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
        }
        if (bean instanceof ResourceLoaderAware) {
            ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
        }
        if (bean instanceof ApplicationEventPublisherAware) {
            ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
        }
        if (bean instanceof MessageSourceAware) {
            ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
        }
        // ApplicationContextAware:实现此接口的类想要拿到ApplicationContext,因此我们在这边赋值给它
        if (bean instanceof ApplicationContextAware) {
            ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
        }
    }
}

四、invokeInitMethods

        如果当前bean实现了InitializingBean 接口,那么这里将会调用该bean重写了的afterPropertiesSet方法。除了InitializingBean接口定义的初始化方法,还会执行我们自定义的initMethod方法。

public interface InitializingBean {

	void afterPropertiesSet() throws Exception;

}
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
        throws Throwable {
 
    // 1.首先检查bean是否实现了InitializingBean接口,如果是的话调用afterPropertiesSet方法
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        if (logger.isDebugEnabled()) {
            logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
        }
        // 2.调用afterPropertiesSet方法
        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 {
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }
 
    if (mbd != null) {
        String initMethodName = mbd.getInitMethodName();
        if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                !mbd.isExternallyManagedInitMethod(initMethodName)) {
            // 3.调用自定义初始化方法
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}

                 invokeCustomInitMethod方法调用我们自定义的初始化方法( xml配置方式中,可在bean属性中设置init-method="initMethod"指定)。 

protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)
        throws Throwable {
    // 1.拿到初始化方法的方法名
    String initMethodName = mbd.getInitMethodName();
    // 2.根据方法名拿到方法
    final Method initMethod = (mbd.isNonPublicAccessAllowed() ?
            BeanUtils.findMethod(bean.getClass(), initMethodName) :
            ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
    if (initMethod == null) {
        // 3.如果不存在initMethodName对应的方法,并且是强制执行初始化方法(默认为强制), 则抛出异常
        if (mbd.isEnforceInitMethod()) {
            throw new BeanDefinitionValidationException("Couldn't find an init method named '" +
                    initMethodName + "' on bean with name '" + beanName + "'");
        } else {    // 如果设置了非强制,找不到则直接返回
            if (logger.isDebugEnabled()) {
                logger.debug("No default init method named '" + initMethodName +
                        "' found on bean with name '" + beanName + "'");
            }
            // Ignore non-existent default lifecycle methods.
            return;
        }
    }
 
    if (logger.isDebugEnabled()) {
        logger.debug("Invoking init method  '" + initMethodName + "' on bean with name '" + beanName + "'");
    }
 
    // 4.调用初始化方法
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
            @Override
            public Object run() throws Exception {
                ReflectionUtils.makeAccessible(initMethod);
                return null;
            }
        });
        try {
            AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                @Override
                public Object run() throws Exception {
                    initMethod.invoke(bean);
                    return null;
                }
            }, getAccessControlContext());
        } catch (PrivilegedActionException pae) {
            InvocationTargetException ex = (InvocationTargetException) pae.getException();
            throw ex.getTargetException();
        }
    } else {
        try {
            ReflectionUtils.makeAccessible(initMethod);
            initMethod.invoke(bean);
        } catch (InvocationTargetException ex) {
            throw ex.getTargetException();
        }
    }
}

五、applyBeanPostProcessorsAfterInitialization

        初始化步骤的最后一步,在初始化后应用BeanPostProcessor的postProcessAfterInitialization方法。

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {
 
    Object result = existingBean;
    // 1.遍历所有注册的BeanPostProcessor实现类,调用postProcessAfterInitialization方法
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
        // 2.在bean初始化方法执行后,调用postProcessAfterInitialization方法
        result = beanProcessor.postProcessAfterInitialization(result, beanName);
        if (result == null) {
            return result;
        }
    }
    return result;
}

        至此,bean初始化的生命周期方法已经全部完成。

结合两篇前文,我们将完整的bean生命周期整理如下:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值