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 的加载流程就先告一段落。