Spring Bean 实例化步骤
- 推断构造方法
- 通过构造方法创建对象
- 填充属性,即依赖注入
- 处理ApplicationContextAware接口的回调,即处理ApplicationContextAware接口的setApplicationContext方法
- 初始化前,即处理@PostConstruct注解的方法
- 初始化,即处理InitializingBean接口的afterPropertiesSet方法
- 初始化后,AOP。
代码验证
BeanInitTest实现了ApplicationContextAware、InitializingBean 接口,且用 @PostConstruct注解声明了初始化前方法,声明了一个切面AopAspectTest,使得BeanInitTest是AOP代理对象。
如果在afterPropertiesSet、setApplicationContext、beforeInit方法上打断点,调试启动,会发现依次顺序进入setApplicationContext、beforeInit、afterPropertiesSet方法。
@Service
public class BeanInitTest implements ApplicationContextAware, InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("初始化");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("ApplicationContextAware 回调方法");
}
@PostConstruct
private void beforeInit(){
System.out.println("初始化前");
}
}
@Component
@Aspect
public class AopAspectTest {
@Pointcut(" execution (* com.ludk.weixin.service.BeanInitTest.*(..))")
public void pointCut(){}
@Before("pointCut()")
public void cutBefore(){
System.out.println("切面方法前");
}
}
代码调试验证
断点选择
在如图所示处打断点,并加上条件beanName.equals(“beanInitTest”),只观察该bean对象实例化,然后调试启动SpringBoot项目
调试观察
进入断点后,如下图所示,左下角是代码调用的堆栈信息,可以看到代码的来源,beanName确实是想监控的bean名称beanInitTest
创建bean的代码分析并验证
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
//创建Bean的时候,会将Bean包装成一个BeanWrapper
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建Bean实例,里面包含推断构造方法,并根据构造方法利用反射实例化Bean对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
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");
}
//将对象工厂放入到Spring的三级缓存中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//填充属性,也就是依赖注入
populateBean(beanName, mbd, instanceWrapper);
//这里会处理ApplicationContextAware接口的回调、执行初始化前(@PostConstruct注解标注的方法)、初始化(InitializingBean接口方法)、初始化后的操作(AOP代理对象生成)
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);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
对象创建
doCreateBean的方法中对象创建的代码如下:
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)方法参数
- String beanName:bean名称
- RootBeanDefinition mbd:bean的定义
- @Nullable Object[] args:构造方法的参数
根据上面的三个参数推断出构造方法,利用java反射创建对象,相当于new了一个对象。
依赖注入
doCreateBean方法中依赖注入的代码如下:
populateBean(beanName, mbd, instanceWrapper);
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)方法参数
- String beanName:bean名称
- RootBeanDefinition mbd:bean的定义
- @Nullable BeanWrapper bw:bean实例的包装类
依赖注入就是属性填充。上一步只是实例化了对象,对象中属性是null需要调用populateBean方法填充属性。
处理回调、初始化前、初始化、初始化后
doCreateBean方法中Bean初始化前、初始化、初始化后的代码如下:
exposedObject = initializeBean(beanName, exposedObject, mbd);
三个方法均打上断点,监控方法的调用链
方法依次进入ApplicationContextAware接口的setApplicationContext方法、InitializingBean接口的afterPropertiesSet方法、@PostConstruct注解注释的beforeInit方法,进入断点后同时观察左下角的方法调用链,分析代码。
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)是初始化bean的方法,里面主要包含初始化前、初始化、初始化后三个步骤。
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//处理Aware接口的回调,其中包括ApplicationContextAware接口的setApplicationContext方法的执行
//初始化前
//都是用BeanProcess的前置处理方法实现的
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//初始化 ,InitializingBean接口的afterPropertiesSet方法
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()) {
//初始化后,包括AOP
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
处理Aware回调
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
getBeanPostProcessors()获取Bean处理器时,有个
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
//通过Bean的处理器,调用前置方法实现
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
BeanPostProcessor 是Bean的处理器,是、在容器初始化时对 bean 的创建过程进行扩展和自定义的接口。getBeanPostProcessors()方法获取各种Bean处理器,遍历调用前置方法,执行Bean初始化前的操作。
调试代码中是通过ApplicationContextAwareProcessor处理器,调用postProcessBeforeInitialization前置方法,就会执行到Bean对象ApplicationContextAware接口的setApplicationContext方法。
初始化前
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
getBeanPostProcessors()获取Bean处理器时,有个CommonAnnotationBeanPostProcessor处理器,该处理器继承了InitDestroyAnnotationBeanPostProcessor处理器。
CommonAnnotationBeanPostProcessor的postProcessBeforeInstantiation实现是空的,因此执行父类InitDestroyAnnotationBeanPostProcessor的postProcessBeforeInitialization方法,最终执行到@PostConstruct注解标注的方法。调用链路如下:
初始化
invokeInitMethods(beanName, wrappedBean, mbd);
通过下面的代码调用
调用链路如下:
初始化后
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
getBeanPostProcessors()获取Bean处理器时,有个AnnotationAwareAspectJAutoProxyCreator处理器,它及它的父类均没有实现postProcessAfterInitialization方法,最后只能执行org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
//这里生成了AOP的代理对象
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
调用链路如下:
需要注意的是,如果是循环依赖的情况,是根据三级缓存中的对象工厂,创建AOP代理对象的。