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

广元 网站建设wordpress加入百度统计

广元 网站建设,wordpress加入百度统计,怎么做视频解析的网站,互联网营销师报考文章目录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/106075.html

相关文章:

  • 做么自己做一个网站房地产市场
  • 邢台网站优化服务平台宁波做网站哪家公司好
  • 郑州建材公司网站建设wordpress彩色框
  • 装饰公司为什么做网站wordpress rss feed
  • 1688企业网站建设网站如何做网站名称
  • 西安企业网站制作价格引擎搜索下载
  • 如何做公司网站运营备案网站名称更改
  • 北京定制网站开发公司浩森宇特u钙网logo设计文字头像
  • 免费下载代码的网站免费做元宵节卡片的网站
  • 越秀网站建设设计公司网站模板侵权案例
  • 云南网站做的好的公司哪家好南通专业制作网站
  • 无忧网站建设报价班徽logo设计图片
  • 大型门户网站江苏纯手工seo
  • 用flash做的网站有哪些珠海百度seo
  • 建设公众号官方网站总结格式模板
  • 人力社保网站建设的意义中国信息网官网查询系统
  • 比价网站开发wordpress采集破解版
  • 网站建设作业多少钱对电子商务网站建设的感想
  • 网站怎样才能被百度收录学校网站asp源码
  • 正能量不良网站免费软件下载电商网站设计论文
  • 芗城区建设局网站seo关键词排名优化怎样收费
  • 东莞网站优化公司哪家好域名估价网站
  • wordpress游戏网站主题网络营销促销形式
  • 重庆网站制作哪家好删除wordpress标志
  • 网站建设的收获体会虾子酱 wordpress
  • 郑州企业自助建站建站系统哪个比较好
  • 在中国做外国网站怎么收钱响应式网站建站平台
  • 社区网站怎么建湖南土特产销售网网站建设制作
  • 章丘网站制作住房和城市建设厅网站
  • 什么网站做贸易好cms下载官方网站