共计 19166 个字符,预计需要花费 48 分钟才能阅读完成。
bean 的加载(五)
前一篇文章次要解说了创立 bean 中的 createBeanInstance 办法和实例化过程。本文持续解说对于 bean 的加载过程中属性注入和注册 DisposableBean。
属性注入 populateBean
理解完循环依赖后,咱们持续看属性填充是如何实现。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {if (bw == null) {if (mbd.hasPropertyValues()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
} else {
// 没有可填充的属性
return;
}
}
// 给 InstantiationAwareBeanPostProcessors 最初一个机会在属性设置前扭转 bean
// 具体通过调用 ibp.postProcessAfterInstantiation 办法,如果调用返回 false, 示意不用持续进行依赖注入,间接返回
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
// 返回值为是否持续填充 bean
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 如果后处理器收回进行填充命令则终止后续的执行
if (!continueWithPropertyPopulation) {return;}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 依据 bean 的依赖注入形式:即是否标注有 @Autowired 注解或 autowire=“byType/byName”的标签
// 会遍历 bean 中的属性,依据类型或名称来实现相应的注入
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 依据名称主动注入
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {// 代码(1)
autowireByName(beanName, mbd, bw, newPvs);
}
// 依据类型主动注入
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {// 代码(2)
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 容器是否注册了 InstantiationAwareBeanPostProcessor
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 是否进行依赖查看
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
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;
}
}
}
// 查看是否满足相干依赖关系,对应的 depends-on 属性,3.0 后已弃用
if (needsDepCheck) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
// 如果 pvs 不为空, 将 pvs 上所有的属性填充到 BeanWrapper 对应的 Bean 实例中
if (pvs != null) {
// 代码(3)applyPropertyValues(beanName, mbd, bw, pvs);
}
}
在 populateBean 办法中解决流程大抵如下:
- InstantiationAwareBeanPostProcessor 处理器中的 postProcessAfterInstantiation 办法的利用,能够控制程序是否持续进行属性填充
- 依据注入类型(byType/byName),提取依赖的 bean,并对立存入 PropertyValues 中
- 利用 InstantiationAwareBeanPostProcessor 处理器的 postProcessPropertyValues 办法,对属性获取结束填充前对属性的再次解决,典型利用就是 RequiredAnnotationBeanPostProcessor 类中对属性的验证
- 将所有 PropertyValues 中的属性填充至 BeanWrapper 中
咱们先剖析一下代码(1)看一下 byName 是如何实现的。
autowireByName
protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 寻找 bw 中须要依赖注入的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
// 查看缓存 bean 中是否存在以后 bean
if (containsBean(propertyName)) {// 递归初始化相干的 bean. 代码(1)
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
// 注册依赖
registerDependentBean(propertyName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Added autowiring by name from bean name'" + beanName +
"'via property'" + propertyName + "'to bean named'" + propertyName + "'");
}
} else {
// 找不到则不解决
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property'" + propertyName + "'of bean'" + beanName +
"'by name: no matching bean found");
}
}
}
}
byName 的解决逻辑很简略,获取须要注入的 bean,而后递归调用 getBean
获取 bean
进行注入。
autowireByType
protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 获取自定义的类型转换器
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {converter = bw;}
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
// 寻找 bw 中须要依赖注入的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
// 获取属性描述符
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// 不要尝试按类型为 Object 类型主动拆卸:即便从技术上讲是不称心的,非简略的属性,也没有意义。if (Object.class != pd.getPropertyType()) {
// 探测指定属性的 set 办法
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
// 解析指定 beanName 的属性所匹配的值, 并把解析到的属性名称存储在 autowiredBeanNames 中, 当属性存在多个封装 bean 时
// 比方: @Autowired private List<A> aList; 就会找到所有匹配 A 类型的 bean 并将其注入
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
// 增加到待注入的 bean 列表中
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
// 注册依赖
registerDependentBean(autowiredBeanName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Autowiring by type from bean name'" + beanName + "'via property'" +
propertyName + "'to bean named'" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();}
} catch (BeansException ex) {throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
- 获取类型转换器,如果没有,默认为 bw
- 获取须要注入的属性
- 对所有属性进行遍历并开始注入,首先排除 Object.class 类型,调用 resolveDependency() 办法进行校验获取对应的 bean
- 放入 pvs 外面,并调用 registerDependentBean() 办法注册对应的依赖和被依赖关系
autowiredBeanNames 属性次要解决汇合类型的注入形式,比方@autowired private List<A> tests
,如果是非汇合类型则该属性并无用处。
咱们看一下重点是如何寻找类型匹配的。进入 resolveDependency 办法中。
DefaultListableBeanFactory#resolveDependency
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
//Optional 类注入的非凡解决
return createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
//ObjectFactory/ObjectProvider 类注入的非凡解决
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
//javaxInjectProviderClass 类注入的非凡解决
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);
if (result == null) {
// 通用解决逻辑
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {return shortcut;}
// 从 descriptor 中获取属性类型
Class<?> type = descriptor.getDependencyType();
// 用于反对注解 @Value
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {if (value instanceof String) {String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {return multipleBeans;}
// 查找合乎注入属性类型的 bean , 这里过滤了 @Bean(autowireCandidate = false)和不合乎 @Qualifier("beanName")的 bean
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
// 为空阐明找不到该注入类型的 bean,如果注入的属性又是必须的,则抛出异样 NoSuchBeanDefinitionException
if (isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
// 查问到多个合乎注入属性类型的 bean
if (matchingBeans.size() > 1) {
// 再次过滤找到最优的 beanName,进而获取最优的用来创立实例的候选者 instanceCandidate
// 这里筛选 @primary、@Priority 等优先级高的 bean
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
// 找不到最优的 beanName,注入的属性又是必须的,则抛 NoUniqueBeanDefinitionException 异样
// 注入的属性非必须,未过滤前就有多个注入属性类型的 bean,如果注入的属性不是汇合,也抛异样
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {return null;}
}
// 依据 beanName 获取最优的用来创立属性实例的候选者 instanceCandidate
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// 确定只有一个匹配项
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();}
if (autowiredBeanNames != null) {autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {if (isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
该办法在寻找类型的匹配执行程序时,首先尝试应用解析器进行解析,如果没有胜利解析,那么可能是应用默认的解析器没有做任何解决,或者应用了自定义解析器,然而对于汇合等类型来说并不在解析范畴内,所以再次对不同类型进行不同状况的解决。
applyPropertyValues
执行到这里后,曾经实现了对所有注入属性的获取,然而获取到的属性都是 PropertyValues 模式,还没有利用到曾经实例化的 bean 中,这一工作都是在 applyPropertyValues 中实现。
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {if (pvs.isEmpty()) {return;}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {mpvs = (MutablePropertyValues) pvs;
// 如果 mpvs 中的值曾经被转换为对应的类型那么能够间接设置到 beanWrapper
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {bw.setPropertyValues(mpvs);
return;
} catch (BeansException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();} else {
// 如果 pvs 并不是应用 MutablePropertyValues 封装的类型, 那么间接应用原始的属性获取办法
original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {converter = bw;}
// 获取对应的解析器
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
// 遍历属性, 将属性转换为对应属性的类型
for (PropertyValue pv : original) {if (pv.isConverted()) {deepCopy.add(pv);
} else {String propertyName = pv.getName();
Object originalValue = pv.getValue();
if (originalValue == AutowiredPropertyMarker.INSTANCE) {Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {throw new IllegalArgumentException("Autowire marker for property without write method:" + pv);
}
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {if (convertible) {pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
} else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
} else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {bw.setPropertyValues(new MutablePropertyValues(deepCopy));
} catch (BeansException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
初始化 bean
咱们晓得在配置 bean 的时候有一个 init-method
的属性,这个属性就是在 bean 实例化前调用所指定的办法,依据业务需要进行相应的实例化,咱们当初还是回到 doCreateBean 中。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {// 代码(1) 激活 Aware 办法
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
// 对非凡的 bean 解决,Aware / BeanClassLoaderAware / BeanFactoryAware
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 调用 bean 后处理器的办法
// BeanPostProcessor 提供的办法,在 bean 初始化前调用,这时的 bean 已实现了实例化和属性填充注入工作
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()) {
// 调用 bean 后处理器的办法
// BeanPostProcessor 提供的办法,在 bean 初始化后调用,这时候的 bean 曾经创立实现了
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
尽管该办法次要目标是执行咱们设置的初始化办法的调用,然而除此之外还有其余必要的工作。
1. 激活 Aware 办法
在理解原理前,咱们先理解一下什么是 Aware,Spring
中提供了一些 Aware 相干接口,比方 BeanFactoryAware、ApplicationContextAware、ResourceLoaderAware、ServletContextAware 等,比方实现了 BeanFactoryAware 的接口的 bean 在初始化后,Spring 容器会注入 BeanFactory 的实例,实现了 ApplicationContextAware 接口的 bean 会被注入到 ApplicationContext 的实例等。
咱们先理解一下 Aware 的应用。
- 定义一个一般 bean
/**
* @author 神秘杰克
* 公众号: Java 菜鸟程序员
* @date 2022/6/8
* @Description
*/
public class Hello {public void say(){System.out.println("hello");
}
}
- 定义 BeanFactoryAware 类型的 bean
/**
* @author 神秘杰克
* 公众号: Java 菜鸟程序员
* @date 2022/6/8
* @Description
*/
public class AwareTest implements BeanFactoryAware {
private BeanFactory beanFactory;
// 申明 bean 的时候 Spring 会主动注入 BeanFactory
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory = beanFactory;}
public void testAware(){
// 通过 beanFactory 获取 hello bean
final Hello hello = (Hello) beanFactory.getBean("hello");
hello.say();}
}
- 注册 bean
<bean id="hello" class="cn.jack.Hello"/>
<bean id="awareTest" class="cn.jack.AwareTest"/>
- 测试
public class Test {public static void main(String[] args) {final ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
final AwareTest awareTest = (AwareTest) applicationContext.getBean("awareTest");
awareTest.testAware();}
}
- 执行后果
hello
依照下面的形式咱们能够获取到 Spring 中的 BeanFactory,并能够依据 BeanFactory 获取所有 bean,以及进行相干设置,其余 Aware 都大同小异。
具体咱们看一下代码(1)调用的办法就能够一下看明确了。非常简单。
private void invokeAwareMethods(final String beanName, final 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);
}
}
}
2. 处理器的利用
BeanPostProcessor 是 Spring 中开放式架构中必不可少的一个亮点,给了用户短缺的权限去更改或者扩大 Spring,除了 BeanPostProcessor 外还有很多其余的 PostProcessor,当然大部分都是以此为根底,继承自 BeanPostProcessor。
在调用咱们自定义初始化办法前后会别离调用 BeanPostProcessor 的 postProcessBeforeInitialization
和postProcessAfterInitialization
办法,使得咱们能够依据业务需要进行响应的解决。
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 获取所有实现了 BeanPostProcessors 接口的类,进行遍历
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 外围办法:postProcessBeforeInitialization
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {return result;}
result = current;
}
return result;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 获取所有实现了 BeanPostProcessors 接口的类,进行遍历
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 外围办法:postProcessAfterInitialization
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {return result;}
result = current;
}
return result;
}
3. 激活自定义的 init 办法
初始化办法除了应用 init-method 外,还有自定义的 bean 实现 InitializingBean 接口,实现 afterPropertiesSet 办法实现本人的初始化业务逻辑。
当然,这两种都是在初始化 bean 的时候执行,履行程序是 afterPropertiesSet 先执行,而 init-method 后执行。
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 先查看是否为 isInitializingBean, 如果是的话先调用 afterPropertiesSet 办法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {if (logger.isTraceEnabled()) {logger.trace("Invoking afterPropertiesSet() on bean with name'" + beanName + "'");
}
// 调用 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();}
}
if (mbd != null && bean.getClass() != NullBean.class) {
// 从 RootBeanDefinition 中获取 initMethod 办法名称
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 调用 initMethod 办法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
须要留神的是,在应用了 @PostConstruct 注解和实现了 InitializingBean 接口和 init-method 的时候。
执行程序为 PostConstruct -> InitializingBean -> init-method
注册 DisposableBean
在 doCreateBean 中还有最初一步,就是注册 bean 到 disposableBeans,以便在销毁 bean 的时候 能够运行指定的相干业务。
除了咱们熟知的 destroy-method 办法外,咱们还能够注册后处理器 DestructionAwareBeanPostProcessor
来对立 bean 的销毁办法。
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
// 如果为单例
if (mbd.isSingleton()) {
/**
* 注册一个 DisposableBean 的实现为以下三种给出的 bean 做所有的销毁工作:* DestructionAwareBeanPostProcessor,DisposableBean,自定义 destroy 办法
*/
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
// 自定义 scope 的解决
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {throw new IllegalStateException("No Scope registered for scope name'" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
至此,Spring bean 的加载流程就先告一段落。