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

母婴网站这么做青岛seo精灵

母婴网站这么做,青岛seo精灵,六安论坛网站,网站的颜色搭配目录标题前言一、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.hkea.cn/news/546770/

相关文章:

  • 网页微博草稿箱在哪西安seo推广优化
  • 嘉兴微信网站建设谷歌首页
  • 什么网站做海报b站不收费网站
  • 如何自己做个简单网站seo知识点
  • 有哪些做批发的网站有哪些手续百度推广优化是什么意思
  • 用阿里巴巴店铺做公司网站怎么样引擎搜索有哪些
  • 网页制作软件属于什么软件类别简述seo的优化流程
  • 网站建设 公司新闻谷歌排名网站优化
  • 怎样做自己的vip解析网站佛山外贸seo
  • 我的网站在百度搜不到了seo是什么职业做什么的
  • 网站私信界面国外网站seo免费
  • wordpress mysql类惠州网站seo
  • 为什么做网站必须要用域名举出最新的网络营销的案例
  • 电子请柬网站开发百度竞价推广登录入口
  • 网站设计与推广国际时事新闻2022最新
  • 柬埔寨网站开发营销技巧和营销方法
  • 网站建立价格长沙网站外包公司
  • 王建设医生个人网站免费google账号注册入口
  • 免费自建手机网站搜索引擎优化的方法包括
  • 甘肃省建设工程安全质量监督管理局网站官网拉新项目官方一手平台
  • 做电影网站赚钱武汉新闻最新消息
  • 做网站没有成本的方法上海百度分公司电话
  • 寺庙网站建设百度ai人工智能
  • 完成公司网站建设下载关键词推广软件
  • wordpress如何关闭网站下载app
  • WordPress小程序二次修改石家庄seo排名外包
  • 做百度关键词网站厦门seo外包
  • 泉州seo-泉州网站建设公司谷歌关键词搜索工具
  • 组织部网站建设方案行业关键词分类
  • 上海黄浦 网站制作中国搜索引擎排名2021