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

大连建设工业产品网站百度高级搜索指令

大连建设工业产品网站,百度高级搜索指令,wordpress a,wordpress 插件本地化目录标题前言一、Bean加载入口与源码分析1、Bean加载的入口2、Bean加载源码二、FactoryBean的使用三、缓存中获取单例bean(待补充)前言 经过前面的分析,我们终于结束了对XML 配置文件的解析,接下来将会面临更大的挑战,就是对 bean 加载的探索…

目录标题

  • 前言
  • 一、Bean加载入口与源码分析
    • 1、Bean加载的入口
    • 2、Bean加载源码
  • 二、FactoryBean的使用
  • 三、缓存中获取单例bean(待补充)

前言

经过前面的分析,我们终于结束了对XML 配置文件的解析,接下来将会面临更大的挑战,就是对 bean 加载的探索。bean 加载的功能实现远比 bean 的解析要复杂得多。

一、Bean加载入口与源码分析

1、Bean加载的入口

讲源码之前,我们可以先来找一下源码入口。对于加载 bean 的功能,在 Spring 中的调用方式为:

MyTestBean bean = (MyTestBean) bf.getBean ("myTestBean")

这句代码实现了什么样的功能呢?我们可以先快速体验一下 Spring 中代码是如何实现的。

2、Bean加载源码

protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {/* 1、转换对应beanName。* 	1.去除FactoryBean的修饰符。name有可能是 &xxx 或者 xxx,如果name是&xxx,那么beanName就是xxx;2.name有可能传入进来的是别名,那么beanName就是id;* */String beanName = transformedBeanName(name);Object beanInstance;/* 2、尝试从缓存中加载单例。*/Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {if (logger.isTraceEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");}else {logger.trace("Returning cached instance of singleton bean '" + beanName + "'");}}/* 3、返回真正的实例.*    缓存中记录的只是最原始的 bean 状态,并不一定是我们最终想要的 bean。*  举个例子,假如我们需要对工厂 bean 进行处理,那么这里得到的其实是工厂 bean 的初始状态,但是我们真正需要的是工厂 bean 中定义的 faetory-method 方法中返回的 bean,*  而 getObjectForBeanInstance 就是完成这个工作的。如果sharedInstance是FactoryBean,那么就调用getObject()返回对象*  */beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {/* 4、原型模式的依赖检查(只有在单例情况才会尝试解决循环依赖;原型模式出现循环依赖会报错。)。*      原型模式情况下,如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖,也就是isPrototypeCurrentlyInCreation (beanName)为true的情况;* */if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}BeanFactory parentBeanFactory = getParentBeanFactory();/* 5、检测parentBeanFactory。*   如果 beanDefinitionMap 中也就是在所有已经加载的类中不包括 beanName, 则尝试从parentBeanFactory 中检测,然后再去递归的调用 getBean 方法。*/if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// Not found -> check parent.// &&&&xxx---->&xxxString nameToLookup = originalBeanName(name);if (parentBeanFactory instanceof AbstractBeanFactory) {return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);}else if (args != null) {// Delegation to parent with explicit args.return (T) parentBeanFactory.getBean(nameToLookup, args);}else if (requiredType != null) {// No args -> delegate to standard getBean method.return parentBeanFactory.getBean(nameToLookup, requiredType);}else {return (T) parentBeanFactory.getBean(nameToLookup);}}if (!typeCheckOnly) {markBeanAsCreated(beanName);}StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);try {if (requiredType != null) {beanCreation.tag("beanType", requiredType::toString);}/* 6、将存储 XML 配置文件的 GenericBeanDefinition 转换为 RootBeanDefinition。*    1.因为从 XML 配置文件中该取到的 Bean 信息是存储在 GenericBeanDefinition 中的,但是所有的 Bean 后续处理都是针对于 RootBeanDefinition 的,所以这里需要进行一个转换;*    2.转换的同时如果父类 bean 不为空的话,则会一并合并交类的属性。* */RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);// 检查BeanDefinition是不是Abstract的checkMergedBeanDefinition(mbd, beanName, args);/* 7、寻找依赖。*    因为 bean 的初始化过程中很可能会用到某些属性,而某些属性很可能是动态配置的,并且配置成依赖于其他的 bean,那么这个时候就有必要先加载依赖的 bean,* 所以,在 Spring 的加载顺寻中,在初始化某一个 bean 的时候首先会初始化这个 bean 所对应的依赖。* */String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {// dependsOn表示当前beanName所依赖的,当前Bean创建之前dependsOn所依赖的Bean必须已经创建好了for (String dep : dependsOn) {// beanName是不是被dep依赖了,如果是则出现了循环依赖if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}// dep被beanName依赖了,存入dependentBeanMap中,dep为key,beanName为valueregisterDependentBean(dep, beanName);// 创建所依赖的beantry {getBean(dep);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}/* 8、针对不同的scope模式进行bean的创建*/// 8.1.singleton模式的创建if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);}catch (BeansException ex) {// Explicitly remove instance from singleton cache: It might have been put there// eagerly by the creation process, to allow for circular reference resolution.// Also remove any beans that received a temporary reference to the bean.destroySingleton(beanName);throw ex;}});beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}// 8.2.prototype模式的创建else if (mbd.isPrototype()) {// It's a prototype -> create a new instance.Object prototypeInstance = null;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}// 8.3.	其他scope类型else {String scopeName = mbd.getScope();if (!StringUtils.hasLength(scopeName)) {throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");}Scope scope = this.scopes.get(scopeName);if (scope == null) {throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");}try {  // session.getAttriute(beaName)  setAttriObject scopedInstance = scope.get(beanName, () -> {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}});beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch (IllegalStateException ex) {throw new ScopeNotActiveException(beanName, scopeName, ex);}}}catch (BeansException ex) {beanCreation.tag("exception", ex.getClass().toString());beanCreation.tag("message", String.valueOf(ex.getMessage()));cleanupAfterBeanCreationFailure(beanName);throw ex;}finally {beanCreation.end();}	}/* 9、类型转换。*     1.程序到这里返回 bean后已经基本结束了,通常对该方法的调用参数 requiredType 是为空的,* 但是可能会存在这样的情况,返回的 bean 其实是个 String,但是 requiredType 却传入 Integer类型,那么这时候本步骤就会起作用了,* 它的功能是将返回的 bean 转换为 requiredType 所指定的类型。*     2.当然,String 转换为 Integer 是最简单的一种转换,在 Spring 中提供了各种各样的转换器,用户也可以自己扩展转换器来满足需求。* */return adaptBeanInstance(name, beanInstance, requiredType);}

经过上面的步骤后 bean 的加载就结束了,这个时候就可以返回我们所需要的 bean 了。其中最重要的就是步骤(8),针对不同的 scope 进行 bean 的创建,你会看到各种常用的 Spring 特性在这里的实现

在细化分析各个步骤提供的功能前,我们有必要先了解下 FactoryBean 的用法。

二、FactoryBean的使用

【Spring学习】FactoryBean的使用

三、缓存中获取单例bean(待补充)

http://www.tj-hxxt.cn/news/16765.html

相关文章:

  • 网站建设主要包括两个方面杭州千锋教育地址
  • 滕州网站建设哪家好深圳疫情最新消息
  • 成都兼职做网站百度网页版登录入口
  • 不让人看出wordpress建的站职业培训机构需要什么资质
  • 百度怎么对网站处罚外包公司和劳务派遣
  • 3d网站建设制作百度推广登录后台登录入口
  • 军队网站建设方案seo优化论坛
  • 网站怎么发内容优化品牌运营策略有哪些
  • 装修设计公司起名seo是广告投放吗
  • 建站工具缺点国内优秀个人网站欣赏
  • 大连专业手机自适应网站建设维护卡点视频免费制作软件
  • 高清做网站插图宽带营销策略
  • 网站开发服务公司站外推广免费网站
  • 自适应网站建设都找全网天下网址导航推广
  • 网站售后维护seo优化服务公司
  • 色调网站百度地图疫情实时动态
  • 怎样登入网站后台如何建网址
  • 自开发网站中国站长之家网站
  • 江门做网站哪家好北京百度总部
  • 广告传媒网站模板软件推广接单平台
  • 贵阳制作网站网络推广渠道公司
  • wordpress学校网站neotv
  • 好看的wordpress文章模板下载seoul是什么国家
  • 高端网站建设设seo关键词排名优化方法
  • 庆云网站建设舆情管理
  • 门户网站建设好处如何建立一个网站平台
  • 种子网站开发公司seo是什么级别
  • 最新军事动态最新消息外包seo服务口碑好
  • 广州小企业网站制作嘉兴seo计费管理
  • 做网站员培训企业邮箱注册申请