目录
2:执行实现了InstantiationAwareBeanPostProcessor的后置处理器
4:将 MergedBeanDefinitionPostProcessors 应用于指定的 bean 定义(后置处理器调用)
1:注册销毁方法 registerDisposableBeanIfNecessary
一、创建bean之初
spring调用 beanFactory.preInstantiateSingletons()此方法完成整个bean生产以及依赖注入,那么在生成bean之前,spring做了哪些事呢?
1.判断bean定义是否是bean工厂
遍历所有beandefinition 非懒加载以及非抽象bean,单例,去执行AbstractBeanFactory.isFactoryBean(beanName) 方法判断是否是重写 SmartFactoryBean接口的isEagerInit方法为true,若设置为true,就会先去创建bean实例
public void preInstantiateSingletons() throws BeansException {
......
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
......
}
2.获取规范的bean name
调用 transformedBeanName 返回实际的 bean 名称,去掉工厂取消引用前缀(如果有,也去掉重复的工厂前缀)。
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}
3.合并bean定义
调用 AbstractBeanFactory.getMergedBeanDefinition 方法 如果给定bean的定义是子bean定义,则通过与父bean合并,返回另外给定bean的RootBeanDefinition。使用递归处理继承父bean定义,子bean的属性覆盖父bean的属性,并将当前bean的属性保存到缓存mergedBeanDefinitions中
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// 一次性bean实例:一次性实例的bean名称。
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null && !mbd.stale) {
return mbd;
}
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
4:检查合并的bean定义
检查是否是设置了抽象bean的属性 在xml的配置bean可以设置抽象bean
protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args)
throws BeanDefinitionStoreException {
if (mbd.isAbstract()) {
throw new BeanIsAbstractException(beanName);
}
}
5:获取所有@DependsOn注解的依赖bean
调用方法 mbd.getDependsOn() 获取在创建bean定义时已设置的依赖bean,并提前生成bean实例。
缓存到dependentBeanMap中便于下次使用直接返回。
// 保证初始化当前bean所依赖的bean。(循环依赖问题)
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
//创建依赖bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
6:确定bean是否是单例或者多例
单例则会调用
getSingleton
方法实现缓存(三级缓存)解决循环依赖问题,再调用钩子方法 调用createBean方法执行创建bean。
非单例bean,会直接调用createBean方法执行创建bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
二、创建bean实例
1.确保bean类已被实际解析
在 resolveBeanClass 方法判断是否已存在 BeanClass ,有直接返回,反之,调用 doResolveBeanClass方法 获取类加载器 加载类返回
调用getDefaultClassLoader方法 获取ClassLoader,先获取Tomcat设置的线程的类加载器,没有找到就获取ClassUtils.class类的类加载器,还没有就获取应用的类加载器
public static ClassLoader getDefaultClassLoader() {
ClassLoader cl = null;
try {
cl = Thread.currentThread().getContextClassLoader();
}
catch (Throwable ex) {
// 无法访问线程上下文 ClassLoader - 回退...
}
if (cl == null) {
// 无线程上下文类加载器 -> 使用此类的类加载器。
cl = ClassUtils.class.getClassLoader();
if (cl == null) {
// getClassLoader() 返回 null 表示引导类加载器
try {
cl = ClassLoader.getSystemClassLoader();
}
catch (Throwable ex) {
//无法访问系统类加载器 - 哦,好吧,也许调用者可以忍受空...
}
}
}
return cl;
}
spring的备注:
返回要使用的默认类加载器:通常是线程上下文类加载器,如果可用;加载 ClassUtils 类的 ClassLoader 将用作后备。
prepareMethodOverrides 判断方法是否有重载状态 默认为rue
2:执行实现了InstantiationAwareBeanPostProcessor的后置处理器
hasInstantiationAwareBeanPostProcessors 确定是否已注册InstantiationAwareBeanPostProcessor类型的beanPostProcessor,此接口实现实例化前的后置处理器。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// 确保bean类在这一点上被实际解析。
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//调用 InstantiationAwareBeanPostProcessor->postProcessBeforeInstantiation
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//调用 InstantiationAwareBeanPostProcessor->postProcessAfterInitialization
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
3:实例化bean
1.确认是否解析beanClass
2.判断多种条件确认使用那种构造器实例化bean,实例化方法分 autowireConstructor和instantiateBean(默认),spring需要去推断如何去实例化bean,逻辑比较复杂!!!
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 确保bean类在这一点上被实际解析。
Class<?> beanClass = resolveBeanClass(mbd, beanName);
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 重新创建同一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);
}
}
// 指定实例化的构造器
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 默认构造的首选构造函数
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 无需特殊处理:只需不使用arg构造函数。
return instantiateBean(beanName, mbd);
}
4:将 MergedBeanDefinitionPostProcessors 应用于指定的 bean 定义(后置处理器调用)
调用 applyMergedBeanDefinitionPostProcessors 遍历所有的beanPostProcessors执行MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition,
作用:修改合并的bean定义属性
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
5:属性赋值
执行 populateBean(beanName, mbd, instanceWrapper) 方法,使用bean定义中的属性值填充给定BeanWrapper中的bean实例。
populateBean方法内会先执行 实例化后的后置处理器 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
接下来spring会处理配置了ByType和ByName的属性,实现属性注入。此注入是spring自带的实现。代码如下:
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 如果适用,根据名称添加基于自动装配的属性值。
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 如果适用,根据类型添加基于自动装配的属性值。
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
最后确认是否存在 InstantiationAwareBeanPostProcessor的属性后置处理器,并执行后置处理器,实现spring扩展。代码如下:
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
6:初始化bean
执行 initializeBean方法,应用给定的属性值,解析对该bean工厂中其他bean的任何运行时引用。必须使用深度复制,因此spring不会永久修改此属性。
首先执行 invokeAwareMethods方法确定是否实现Aware接口,并处理相关的属性设置,代码如下:
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
执行初始化前后置处理器 BeanPostProcessor.postProcessBeforeInitialization(result, beanName),如后置处理器有返回,直接返回bean实例
接下来执行初始化方法invokeInitMethods(beanName, wrappedBean, mbd)
最后执行初始化后后置处理器,完成bean实例初始化。代码如下:
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
四:销毁
1:注册销毁方法 registerDisposableBeanIfNecessary
此方法会执行 DestructionAwareBeanPostProcessor的后置处理器
五:总结草图
六 :补充说明
1:spring 如何确定使用哪种构造器实例化bean?
1,遍历所有的beanPostProcessors,调用实现了 SmartInstantiationAwareBeanPostProcessor接口的 determineCandidateConstructors方法。
此处可以自定义用于给定 bean 的候选构造函数的处理,可参考spring中AutowiredAnnotationBeanPostProcessor类中对于determineCandidateConstructors方法的实现。
代码实现如下:
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
}
return null;
}
2:spring推断获取构造函数
掉用 BeanUtils.findPrimaryConstructor(clazz) 方法获取主构造函数,若没有找到,执行clazz.getConstructors()方法去找合适的构造函数(?) ,代码实现如下:
public Constructor<?>[] getPreferredConstructors() {
Class<?> clazz = getBeanClass();
//返回所提供类的主构造函数
Constructor<?> primaryCtor = BeanUtils.findPrimaryConstructor(clazz);
if (primaryCtor != null) {
return new Constructor<?>[] {primaryCtor};
}
Constructor<?>[] publicCtors = clazz.getConstructors();
if (publicCtors.length > 0) {
return publicCtors;
}
return null;
}
3:以上都没有获取到构造函数就使用默认构造函数实例化给定的bean,代码实现如下:
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
2:初始化bean的方式有几种?
1:继承InitializingBean的接口,并实现 afterPropertiesSet方法实现,spring代码实现如下:
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
2:通过@bean或者XML标签中有设置initMethod属性,spring代码实现如下:
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}