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

合肥网站建设讯息广元 网站建设

合肥网站建设讯息,广元 网站建设,做设计找参考的设计网站有哪些,网站优化与seo文章目录1 前言2 BeanDefinition合并2.1 BeanDefinition合并在做什么#xff1f;2.2 BeanDefinition怎么合并2.3 示例演示3 Bean Class 加载后记1 前言 下面要介绍的阶段#xff0c;都是在调用getBean()从容器中获取bean对象的过程中发生的操作#xff0c;我们需要更多的去… 文章目录1 前言2 BeanDefinition合并2.1 BeanDefinition合并在做什么2.2 BeanDefinition怎么合并2.3 示例演示3 Bean Class 加载后记1 前言 下面要介绍的阶段都是在调用getBean()从容器中获取bean对象的过程中发生的操作我们需要更多的去跟进源码。 在以后的讲解中我们都采用API配置bean的方式通过BeanDefinitionBuilder来完成bean的配置。 2 BeanDefinition合并 BeanDefinition合并核心方法 org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefinition()2.1 BeanDefinition合并在做什么 不管我们在定义bean的时候bean有没有父子关系。容器在注册初始BeanDefinition后后续的相关操作都是在使用合并后的RootBeanDefinition。RootBeanDefinition会放入mergedBeanDefinitions中。 private final MapString, RootBeanDefinition mergedBeanDefinitions new ConcurrentHashMap(256);mergedBeanDefinitionsAbstractBeanFactory类中存放beanName-RootBeanDefinition键值对的map 定义了bean当然是为了使用我们通过追踪下getBean()方法看看是不是如上面我们所描述的一样是使用RootBeanDefinition而不是初始BeanDefinition。 factory.getBean()是调用AbstractBeanFactory中的方法 Overridepublic Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);}继续调用doGetBean()方法 protected T T doGetBean(String name, Nullable ClassT requiredType, Nullable Object[] args, boolean typeCheckOnly)throws BeansException {// 如果是别名转换为最初的beanNameString beanName transformedBeanName(name);Object beanInstance;// Eagerly check singleton cache for manually registered singletons.Object sharedInstance getSingleton(beanName);if (sharedInstance ! null args null) {// 我们第一次获取bean容器中不会有bean实例// 省略...}else {// 省略...StartupStep beanCreation this.applicationStartup.start(spring.beans.instantiate).tag(beanName, name);try {if (requiredType ! null) {beanCreation.tag(beanType, requiredType::toString);}// 后续使用中使用的是合并后的RootBeanDefinitionRootBeanDefinition mbd getMergedLocalBeanDefinition(beanName);// 省略... }2.2 BeanDefinition怎么合并 我们通过源码来详细看看是如果合并的。在上面我们已经通过源码追踪到了执行合并的方法getMergedLocalBeanDefinition(),源码如下 protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {// Quick check on the concurrent map first, with minimal locking.RootBeanDefinition mbd this.mergedBeanDefinitions.get(beanName);if (mbd ! null !mbd.stale) {// 第一次获取mergedBeanDefinitions并不会有beanName对应的RootBeanDefinitionreturn mbd;}return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); }getBeanDefinition(beanName)获取初始注册的BeanDefinition 继续调用getMergedBeanDefinition() protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)throws BeanDefinitionStoreException {return getMergedBeanDefinition(beanName, bd, null);}继续调用getMergedBeanDefinition()即合并BeanDefinition的主要方法 protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, Nullable BeanDefinition containingBd)throws BeanDefinitionStoreException {synchronized (this.mergedBeanDefinitions) {RootBeanDefinition mbd null;RootBeanDefinition previous null;// Check with full lock now in order to enforce the same merged instance.if (containingBd null) {mbd this.mergedBeanDefinitions.get(beanName);}if (mbd null || mbd.stale) {previous mbd;if (bd.getParentName() null) {// 父bean为空// Use copy of given root bean definition.if (bd instanceof RootBeanDefinition) {// 原始的BeanDefinition为RootBeanDefinition直接克隆mbd ((RootBeanDefinition) bd).cloneBeanDefinition();}else {// 原始的BeanDefinition不是RootBeanDefinitionnewmbd new RootBeanDefinition(bd);}}else {// 父bean不为空需要合并BeanDefinition pbd;try {String parentBeanName transformedBeanName(bd.getParentName());if (!beanName.equals(parentBeanName)) {// 默认beanName唯一获取map中parentBeanName对应的RootBeanDefinitionpbd getMergedBeanDefinition(parentBeanName);}// 省略...// new深拷贝mbd new RootBeanDefinition(pbd);// 子bean初始BeanDefinition的相关信息覆盖掉继承自RootBeanDefinition的相同信息mbd.overrideFrom(bd);}// 省略...return mbd;}}合并逻辑如下 我们定义的bean没有父子关系时合并bean其实就是新生成RootBeanDefinition对象内容拷贝自初始BeanDefinition并放入mergedBeanDefinitions集合;如果bean就是定义的RootBeanDefinition直接拷贝。 我们定义bean的有父子bean关系时此时子BeanDefinition中的信息是不完整的比如设置属性的时候配置在父BeanDefinition中此时子BeanDefinition中是没有这些信息的。需要将子bean的BeanDefinition和从mergedBeanDefinitions集合获取的父bean对应的RootBeanDefinition进行合并得到最终的一个RootBeanDefinition合并之后得到的RootBeanDefinition包含bean定义的所有信息包含了从父bean中继继承过来的所有信息后续bean的所有创建工作就是依靠合并之后RootBeanDefinition来进行的。 当定义的bean有多级父子关系重复上述步骤合并当前bean的初始BeanDefinition和从mergedBeanDefinitions 映射中获取父beanName对应的RootBeanDefinition。 2.3 示例演示 因为是做演示测试没有通过factory.getBean()去debug调试而是直接调用getMergedBeanDefinition()方法。 // User package com.gaogzhen.myspring.bean;/*** author: Administrator* version: 1.0* createTime: 2023/02/20 07:49*/ public class User {private String name;public void setName(String name) {this.name name;}Overridepublic String toString() {return User{ name name \ };} }// 测试方法public void testMergeAPI() {DefaultListableBeanFactory factory new DefaultListableBeanFactory();BeanDefinitionBuilder builder1 BeanDefinitionBuilder.genericBeanDefinition(User.class).addPropertyValue(name, 张三).addPropertyValue(desc, 创立张氏制药厂);factory.registerBeanDefinition(user1, builder1.getBeanDefinition());BeanDefinitionBuilder builder2 BeanDefinitionBuilder.genericBeanDefinition().addPropertyValue(name, 张小三).addPropertyValue(desc, 接管张氏制药厂).addPropertyValue(manage, 开设分厂).setParentName(user1);factory.registerBeanDefinition(user2, builder2.getBeanDefinition());BeanDefinitionBuilder builder3 BeanDefinitionBuilder.genericBeanDefinition().addPropertyValue(name, 张小小三).addPropertyValue(operate, 成立张氏制药集团并上市).setParentName(user2);factory.registerBeanDefinition(user3, builder3.getBeanDefinition());//遍历容器中注册的所有bean信息for (String beanName : factory.getBeanDefinitionNames()) {//通过bean名称获取原始的注册的BeanDefinition信息BeanDefinition beanDefinition factory.getBeanDefinition(beanName);//获取合并之后的BeanDefinition信息BeanDefinition mergedBeanDefinition factory.getMergedBeanDefinition(beanName);// 获取beanSystem.out.println(beanName);System.out.println(初始beanDefinition beanDefinition);System.out.println(beanDefinition中的属性信息 beanDefinition.getPropertyValues());System.out.println(-----------);System.out.println(合并之后mergedBeanDefinition mergedBeanDefinition);System.out.println(mergedBeanDefinition中的属性信息 mergedBeanDefinition.getPropertyValues());System.out.println();}}打印输出 user1 初始beanDefinitionGeneric bean: class [com.gaogzhen.myspring.bean.User]; scope; abstractfalse; lazyInitnull; autowireMode0; dependencyCheck0; autowireCandidatetrue; primaryfalse; factoryBeanNamenull; factoryMethodNamenull; initMethodNamenull; destroyMethodNamenull beanDefinition中的属性信息PropertyValues: length2; bean property name; bean property desc ----------- 合并之后mergedBeanDefinitionRoot bean: class [com.gaogzhen.myspring.bean.User]; scopesingleton; abstractfalse; lazyInitnull; autowireMode0; dependencyCheck0; autowireCandidatetrue; primaryfalse; factoryBeanNamenull; factoryMethodNamenull; initMethodNamenull; destroyMethodNamenull mergedBeanDefinition中的属性信息PropertyValues: length2; bean property name; bean property descuser2 初始beanDefinitionGeneric bean with parent user1: class [null]; scope; abstractfalse; lazyInitnull; autowireMode0; dependencyCheck0; autowireCandidatetrue; primaryfalse; factoryBeanNamenull; factoryMethodNamenull; initMethodNamenull; destroyMethodNamenull beanDefinition中的属性信息PropertyValues: length3; bean property name; bean property desc; bean property manage ----------- 合并之后mergedBeanDefinitionRoot bean: class [com.gaogzhen.myspring.bean.User]; scopesingleton; abstractfalse; lazyInitnull; autowireMode0; dependencyCheck0; autowireCandidatetrue; primaryfalse; factoryBeanNamenull; factoryMethodNamenull; initMethodNamenull; destroyMethodNamenull mergedBeanDefinition中的属性信息PropertyValues: length3; bean property name; bean property desc; bean property manageuser3 初始beanDefinitionGeneric bean with parent user2: class [null]; scope; abstractfalse; lazyInitnull; autowireMode0; dependencyCheck0; autowireCandidatetrue; primaryfalse; factoryBeanNamenull; factoryMethodNamenull; initMethodNamenull; destroyMethodNamenull beanDefinition中的属性信息PropertyValues: length2; bean property name; bean property operate ----------- 合并之后mergedBeanDefinitionRoot bean: class [com.gaogzhen.myspring.bean.User]; scopesingleton; abstractfalse; lazyInitnull; autowireMode0; dependencyCheck0; autowireCandidatetrue; primaryfalse; factoryBeanNamenull; factoryMethodNamenull; initMethodNamenull; destroyMethodNamenull mergedBeanDefinition中的属性信息PropertyValues: length4; bean property name; bean property desc; bean property manage; bean property operate Process finished with exit code 0 从输出的结果中可以看到合并之前BeanDefinition是不完整的比比如user2和user3中的class是null属性信息也不完整但是合并之后这些信息都完整了。 bean生命周期的后续阶段使用的是合并后的RootBeanDefinition。没有父bean的直接new RootBeanDefinition属性拷贝自该bean的初始BeanDefinition有父bean的深拷贝父bean对应的RootBeanDefinition然后用该bean的初始BeanDefinition覆盖相同属性。 3 Bean Class 加载 这个阶段就是将bean的class名称转换为Class类型的对象。 BeanDefinition中有个Object类型的字段beanClass private volatile Object beanClass;用来表示bean的class对象通常这个字段的值有2种类型一种是bean对应的Class类型的对象另一种是bean对应的Class的类名或者类路径第一种情况不需要解析第二种情况即这个字段是bean的类名的时候就需要通过类加载器将其转换为一个Class对象。 此时会对阶段4中合并产生的RootBeanDefinition中的beanClass进行解析将bean的类名转换为Class对象然后赋值给beanClass字段。 源码位置 org.springframework.beans.factory.support.AbstractBeanFactory#resolveBeanClass()在BeanDefinition合并阶段我们追踪到了AbstracBeanFactory的doGetbean方法完成BeanDefinition合并我们继续追踪看下在哪里完成beanClass的加载具体加载怎么做的 protected T T doGetBean(String name, Nullable ClassT requiredType, Nullable Object[] args, boolean typeCheckOnly)throws BeansException {// 省略RootBeanDefinition mbd getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);// 省略// Create bean instance.if (mbd.isSingleton()) {// 我们通常bean scope都是单例的sharedInstance getSingleton(beanName, () - {try {return createBean(beanName, mbd, args);}catch (BeansException ex) {destroySingleton(beanName);throw ex;}}); // 省略... }getSingleton()方法获取bean的单例实例 public Object getSingleton(String beanName, ObjectFactory? singletonFactory) {Assert.notNull(beanName, Bean name must not be null);synchronized (this.singletonObjects) {Object singletonObject this.singletonObjects.get(beanName);if (singletonObject null) {if (this.singletonsCurrentlyInDestruction) {// 省略...try {singletonObject singletonFactory.getObject();// 省略 }singletonObject初始为空通过上一步传递的singletonFactory获取实例即箭头函数里面return createBean(beanName, mbd, args)继续看下createBean()方法继续调用AbstractAutowireCapableBeanFactory中的createBean()方法 protected Object createBean(String beanName, RootBeanDefinition mbd, Nullable Object[] args)throws BeanCreationException {RootBeanDefinition mbdToUse mbd;// 这里解析beanClassClass? resolvedClass resolveBeanClass(mbd, beanName); // 省略.. }继续调用AbstractBeanFactory中的resolveBeanClass()方法 Nullable protected Class? resolveBeanClass(RootBeanDefinition mbd, String beanName, Class?... typesToMatch)throws CannotLoadBeanClassException {try {if (mbd.hasBeanClass()) {return mbd.getBeanClass();}return doResolveBeanClass(mbd, typesToMatch); // 省略异常处理 }public boolean hasBeanClass() {return (this.beanClass instanceof Class);}先判断RootBeanDefinition mbd中beanClass是否是Class类型是直接返回不是说明是类路径字符串调用doResolveBeanClass解析 查看doResolveBeanClass()方法 Nullable private Class? doResolveBeanClass(RootBeanDefinition mbd, Class?... typesToMatch)throws ClassNotFoundException {ClassLoader beanClassLoader getBeanClassLoader();ClassLoader dynamicLoader beanClassLoader;boolean freshResolve false;// 省略...String className mbd.getBeanClassName();if (className ! null) {Object evaluated evaluateBeanDefinitionString(className, mbd);if (!className.equals(evaluated)) {// 省略...}// Resolve regularly, caching the result in the BeanDefinition...return mbd.resolveBeanClass(beanClassLoader); }如果指定了beanExpressionResolver通过beanExpressionResolver解析默认未指定 我们继续查找AbstracBeanDefinition 的resolveBeanClass方法 Nullablepublic Class? resolveBeanClass(Nullable ClassLoader classLoader) throws ClassNotFoundException {String className getBeanClassName();if (className null) {return null;}Class? resolvedClass ClassUtils.forName(className, classLoader);this.beanClass resolvedClass;return resolvedClass;} classUtils的forName()方法 public static Class? forName(String name, Nullable ClassLoader classLoader)throws ClassNotFoundException, LinkageError {Assert.notNull(name, Name must not be null);Class? clazz resolvePrimitiveClassName(name);if (clazz null) {clazz commonClassCache.get(name);}if (clazz ! null) {return clazz;}// 省略.. 非常规ClassLoader clToUse classLoader;if (clToUse null) {clToUse getDefaultClassLoader();}try {return Class.forName(name, false, clToUse);}// 异常处理.. }通常我们配置的类路径形式包名类名字符串通过Class.forName(name, false, clToUse)加载。 后记 ❓QQ:806797785 ⭐️源代码仓库地址https://gitee.com/gaogzhen/spring6-study 参考 [1]Spring系列之Bean生命周期详解[CP/OL].
http://www.dnsts.com.cn/news/195594.html

相关文章:

  • 个人网站页面设计素材html前端网站开发PPT
  • 怎么做电商网站 用户画像足球网站网站建设
  • 北京网站推广公司金坛做网站的
  • 您的网站未备案 或者原备案号被取消wordpress增加备案
  • 成都那家网站做的好网站建设律师
  • 做推广的网站带宽需要多少合适做特产网站
  • 泰安市房产交易中心官网网站seo快速优化技巧
  • 湖北民族建设集团网站首页外部门户网站首页
  • 全球网站访问量排名公司名字大全免费取名
  • 网站建设与管理A卷wordpress页面增加目录
  • 模板做的网站如何下载wordpress 主题和插件下载失败
  • 环境设计排版哪个网站好安装wordpress 建立数据库连接时出错
  • 网站行高wordpress 适合程序员
  • 重庆秀山网站建设费用Wordpress 分表分库
  • 建设银行银行信用卡中心网站怎么做挖矿网站
  • 电子商务网站建设需要多少钱网站设计怎么做ppt答辩
  • es网站开发北京市网站建设企业
  • 东莞网站建设环保设备货运网站建设公司
  • 做中东服装有什么网站app网站
  • 做瞹瞹网站湘潭企业seo优化哪家好
  • 整站建设和网站优化低价做营销企业网站
  • 网络公司 建站 官方网站美食 wordpress
  • 在线网站制作工具手机网站建设公司哪家好
  • 上海做网站技术那个网站可以看高速的建设情况
  • 网站安全狗 拦截301网站 刷流量 SEO
  • 医院网站建设技术方案ppt网站续费后还是无法访问
  • 电子商务网站的建设报告网站服务器租用怎么购买
  • 如何写网站建设报告怎么做简单的网站首页
  • python整合网站开发技术seo是什么职业
  • 中国十大网站html网页制作步骤