当前位置: 首页 > news >正文

Spring-createBean部分源码

createBean源码:

/*** Central method of this class: creates a bean instance,* populates the bean instance, applies post-processors, etc.* @see #doCreateBean*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {
​if (logger.isTraceEnabled()) {logger.trace("Creating instance of bean '" + beanName + "'");}RootBeanDefinition mbdToUse = mbd;
​// Make sure bean class is actually resolved at this point, and// clone the bean definition in case of a dynamically resolved Class// which cannot be stored in the shared merged bean definition.// 马上就要实例化Bean了,确保beanClass被加载了Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}
​// Prepare method overrides.try {mbdToUse.prepareMethodOverrides();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);}
​try {// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.// 实例化前Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean;}}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);}
​try {Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {// A previously detected exception with proper bean creation context already,// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.throw ex;}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);}
}
​
/*** Resolve the bean class for the specified bean definition,* resolving a bean class name into a Class reference (if necessary)* and storing the resolved Class in the bean definition for further use.* @param mbd the merged bean definition to determine the class for* @param beanName the name of the bean (for error handling purposes)* @param typesToMatch the types to match in case of internal type matching purposes* (also signals that the returned {@code Class} will never be exposed to application code)* @return the resolved bean class (or {@code null} if none)* @throws CannotLoadBeanClassException if we failed to load the class*/
@Nullable
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)throws CannotLoadBeanClassException {
​try {// 如果beanClass被加载了,return (this.beanClass instanceof Class);if (mbd.hasBeanClass()) {return mbd.getBeanClass();}
​// 如果beanClass没有被加载if (System.getSecurityManager() != null) {return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());}else {return doResolveBeanClass(mbd, typesToMatch);}}catch (PrivilegedActionException pae) {ClassNotFoundException ex = (ClassNotFoundException) pae.getException();throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);}catch (ClassNotFoundException ex) {throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);}catch (LinkageError err) {throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);}
}
​
@Nullable
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)throws ClassNotFoundException {
​ClassLoader beanClassLoader = getBeanClassLoader();ClassLoader dynamicLoader = beanClassLoader;boolean freshResolve = false;
​if (!ObjectUtils.isEmpty(typesToMatch)) {// When just doing type checks (i.e. not creating an actual instance yet),// use the specified temporary class loader (e.g. in a weaving scenario).ClassLoader tempClassLoader = getTempClassLoader();if (tempClassLoader != null) {dynamicLoader = tempClassLoader;freshResolve = true;if (tempClassLoader instanceof DecoratingClassLoader) {DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;for (Class<?> typeToMatch : typesToMatch) {dcl.excludeClass(typeToMatch.getName());}}}}
​String className = mbd.getBeanClassName();if (className != null) {// 解析Spring表达式,有可能直接返回了一个Class对象Object evaluated = evaluateBeanDefinitionString(className, mbd);if (!className.equals(evaluated)) {// A dynamically resolved expression, supported as of 4.2...if (evaluated instanceof Class) {return (Class<?>) evaluated;}else if (evaluated instanceof String) {className = (String) evaluated;freshResolve = true;}else {throw new IllegalStateException("Invalid class name expression result: " + evaluated);}}if (freshResolve) {// When resolving against a temporary class loader, exit early in order// to avoid storing the resolved Class in the bean definition.if (dynamicLoader != null) {try {return dynamicLoader.loadClass(className);}catch (ClassNotFoundException ex) {if (logger.isTraceEnabled()) {logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);}}}return ClassUtils.forName(className, dynamicLoader);}}
​// Resolve regularly, caching the result in the BeanDefinition...return mbd.resolveBeanClass(beanClassLoader);
}
​
/*** Apply before-instantiation post-processors, resolving whether there is a* before-instantiation shortcut for the specified bean.* @param beanName the name of the bean* @param mbd the bean definition for the bean* @return the shortcut-determined bean instance, or {@code null} if none*/
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {Object bean = null;if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {// Make sure bean class is actually resolved at this point.// synthetic表示合成,如果某些Bean式合成的,那么则不会经过BeanPostProcessor的处理if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {Class<?> targetType = determineTargetType(beanName, mbd);if (targetType != null) {bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if (bean != null) {bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}mbd.beforeInstantiationResolved = (bean != null);}return bean;
}
​
/*** Apply InstantiationAwareBeanPostProcessors to the specified bean definition* (by class and name), invoking their {@code postProcessBeforeInstantiation} methods.* <p>Any returned object will be used as the bean instead of actually instantiating* the target bean. A {@code null} return value from the post-processor will* result in the target bean being instantiated.* @param beanClass the class of the bean to be instantiated* @param beanName the name of the bean* @return the bean object to use instead of a default instance of the target bean, or {@code null}* @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation*/
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);if (result != null) {// 注意:返回的类型没判断,可以和参数beanClass类型不一样return result; // 有结果就返回,没有结果循环。实例化前取第一个}}return null;
}
​
@Override
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;
}

doCreateBean源码:

/*** Actually create the specified bean. Pre-creation processing has already happened* at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.* <p>Differentiates between default bean instantiation, use of a* factory method, and autowiring a constructor.* @param beanName the name of the bean* @param mbd the merged bean definition for the bean* @param args explicit arguments to use for constructor or factory method invocation* @return a new instance of the bean* @throws BeanCreationException if the bean could not be created* @see #instantiateBean* @see #instantiateUsingFactoryMethod* @see #autowireConstructor*/
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {
​// 实例化bean// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {// 有可能在本Bean创建之前,就有其他Bean把当前Bean给创建出来了(比如依赖注入过程中)instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {// 创建Bean实例instanceWrapper = createBeanInstance(beanName, mbd, args);}Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}
​// 后置处理合并后的BeanDefinition// 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");}// 循环依赖-添加到三级缓存addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}
​// Initialize the bean instance.Object exposedObject = bean;try {// 属性填充populateBean(beanName, mbd, instanceWrapper);
​// 初始化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)) {// beanName被哪些bean依赖了,现在发现beanName所对应的bean对象发生了改变,那么则会报错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;
}

总结BeanPostProcessor

1、InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()

2、实例化

3、MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()

4、InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()

5、自动注入

6、InstantiationAwareBeanPostProcessor.postProcessProperties()

7、Aware对象

8、BeanPostProcessor.postProcessBeforeInitialization()

9、初始化

10、BeanPostProcessor.postProcessAfterInitialization()

http://www.lryc.cn/news/217446.html

相关文章:

  • 2015年亚太杯APMCM数学建模大赛C题识别网络中的错误连接求解全过程文档及程序
  • js:可选链运算符(?.)和空值合并运算符(??)
  • 【Java 进阶篇】Java ServletContext功能:获取文件服务器路径
  • Android startActivity流程
  • Qt实验室
  • diffusers-Load adapters
  • CVI 串口调试助手
  • 【蓝桥杯选拔赛真题48】python最小矩阵 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析
  • 如何在家庭网络中开启 IPv6内网穿透
  • CodeWhisperer 的安装及体验
  • 【C/C++】虚析构和纯虚析构
  • 第四章 应用SysML基本特性集的汽车示例 P1|系统建模语言SysML实用指南学习
  • C语言 写一个简易音乐播放器
  • 面试题:有一个 List 对象集合,如何优雅地返回给前端?
  • DAY43 完全背包理论基础 + 518.零钱兑换II
  • unity 从UI上拖出3D物体,(2D转3D)
  • win10pycharm和anaconda安装和环境配置教程
  • [C++ 中]:6.类和对象下(static成员 + explicit +友元函数 + 内部类 + 编译器优化)
  • ONES Design UI 组件库环境搭建
  • 支付宝AI布局: 新产品助力小程序智能化,未来持续投入加速创新
  • taro全局配置页面路由和tabBar页面跳转
  • 【k8s】pod进阶
  • 【设计模式】第18节:行为型模式之“迭代器模式”
  • 【数据结构】单链表OJ题
  • 智能工厂架构
  • 阿里云多款ECS产品全面升级 性能最多提升40%
  • 责任链模式(Chain of Responsibility)
  • 文件管理技巧:根据大小智能分类并移动至目标文件夹
  • 具有自主产权的SaaS门店收银系统全套源码输出
  • 论文阅读:One Embedder, Any Task: Instruction-Finetuned Text Embeddings