Spring源码之bean的加载(五)准备创建bean
我们继续跟踪代码到createBean,也就是创建创建bean,一同来看一下createBean函数中做了哪些准备工作。首先,我们先来看一张时序图。(相关资源可到这里下载:http://pan.baidu.com/s/1sjSo9a9)
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {if (logger.isDebugEnabled()) {logger.debug("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.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);}Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isDebugEnabled()) {logger.debug("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}
从代码中,我们可以做以下的总结:
1) 根据设置的class属性或者根据className来解析Class。
2) 对override属性进行标记及验证
public void prepareMethodOverrides() throws BeanDefinitionValidationException {// Check that lookup methods exists.MethodOverrides methodOverrides = getMethodOverrides();if (!methodOverrides.isEmpty()) {for (MethodOverride mo : methodOverrides.getOverrides()) {prepareMethodOverride(mo);}}}
上面的方法中,我们要留意的是prepareMethodOverride函数,所以下面是这个函数的实现。
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {//获取对应类中对应方法的个数int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());if (count == 0) {throw new BeanDefinitionValidationException("Invalid method override: no method with name '" + mo.getMethodName() +"' on class [" + getBeanClassName() + "]");}else if (count == 1) {// Mark override as not overloaded, to avoid the overhead of arg type checking.mo.setOverloaded(false);}}
3) 应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作
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.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;}
上述方法,我们关心的是applyBeanPostProcessorsAfterInitialization的方法,下面给出其代码。
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {result = beanProcessor.postProcessAfterInitialization(result, beanName);if (result == null) {return result;}}return result;}
4) 创建bean
Spring源码之bean的加载(五)准备创建bean相关推荐
- Spring源码解析-applicationContext.xml加载和bean的注册
applicationContext文件加载和bean注册流程 Spring对于从事Java开发的boy来说,再熟悉不过了,对于我们这个牛逼的框架的介绍就不在这里复述了,Spring这个大杂烩,怎 ...
- 【框架源码】Spring源码解析之BeanDefinition加载流程解析
观看本文之前,我们先思考一个问题,Spring是如何描述Bean对象的? Spring是根据BeanDefinition来创建Bean对象,BeanDefinition就是Spring中表示Bean定 ...
- Android 11.0 Settings源码分析 - 主界面加载
Android 11.0 Settings源码分析 - 主界面加载 本篇主要记录AndroidR Settings源码主界面加载流程,方便后续工作调试其流程. Settings代码路径: packag ...
- 基于 GoogleMap 离线 API 源码在内网中加载卫星地图的方法
1. 概述 我们之前为大家分享过在三维地球开源平台离线加载卫星影像的方法,主要包括基于桌面端的OsgEarth开源三维地球和基于Web端的Cesium开源三维地球等平台的局域网离线加载. 另外,也为大 ...
- android资源加载流程6,FrameWork源码解析(6)-AssetManager加载资源过程
之前一段时间项目比较忙所以一直没有更新,接下来准备把插件化系列的文章写完,今天我们就先跳过ContentProvider源码解析来讲资源加载相关的知识,资源加载可以说是插件化非常重要的一环,我们很有必 ...
- 《Spring源码深度解析 郝佳 第2版》bean的加载、循环依赖的解决
往期博客: <Spring源码深度解析 郝佳 第2版>容器的基本实现与XML文件的加载 <Spring源码深度解析 郝佳 第2版>XML标签的解析 往期博客完成了xml文件加载 ...
- 有没有code能改xml内容_Spring源码解析-applicationContext.xml加载和bean的注册
applicationContext文件加载和bean注册流程 Spring对于从事Java开发的boy来说,再熟悉不过了,对于我们这个牛逼的框架的介绍就不在这里复述了,Spring这个大杂烩,怎 ...
- Spring源码之BeanDifinition(加几行代码,可以产出让队友几天也找不出的Bug)
前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206/six-finger 种一棵树最好的时间是十年前,其次是现在 我知道很多人不玩qq ...
- JVM源码阅读-本地库加载流程和原理
前言 本文主要研究OpenJDK中JVM源码中涉及到native本地库的加载流程和原理的部分.主要目的是为了了解本地库是如何被加载到虚拟机,以及是如何找到并执行本地库里的本地方法,以及JNI的 JNI ...
- 【Android源码】Activity如何加载布局
我们都知道在Activity中通过setContentView(layoutId)来加载布局文件,使我们的布局文件能够显示在手机上,那么系统是如何将我们的布局文件加载到界面上的呢? setConten ...
最新文章
- C#数据导出Excel详细介绍
- vs插件ZunKoIDE
- input python_Python input 使用
- Oracle 创建,查询,删除 job
- 教你如何配置Tomcat 绑定指定目录的工程文件
- bootstrap-表单控件——单选按钮水平排列
- python resize_Python resize
- 微信红包系统架构的设计和优化分享
- asp.net如何给每张图片动态添加水印方法(二)
- 让IE6-IE8 支持HTML5
- Hibernate学习笔记_查询
- YC StartupSchool 2018 2019 笔记
- JDK6升级JDK8踩雷
- 学UI设计要学哪些软件
- php 威盾加密解密,解析php加密解密混淆的手段,如 phpjm,phpdp神盾,php威盾
- 我的爱好作文玩计算机800,我的爱好作文800字
- 主板没有rgb接口怎么接灯_DIY只为玩游戏?主板配上RGB灯让机箱发光
- CRC16校验使用体验
- 2022施工员-市政方向-通用基础(施工员)题库及答案
- 如何在html中插入本地音乐