ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

beanFactory创建流程 以及BeanDefinition的装填 自定义spring标签

2021-11-11 09:33:03  阅读:150  来源: 互联网

标签:String 自定义 beanFactory 对象 spring public 方法 我们 属性


大家都知道 在spring的流程中beanFactory是非常重要的东西 接下来我们带大家来走一遍beanFactory创建的流程
我们直接开门见山进入方法中 下述方法就是创建beanFactory的方法并且将BeanDefinition中的对象装入beanFactory中 我们仔细进入查看
在这里插入图片描述
进入refresh方法 下面的方法一看就知道 是当我们创建完bean工厂后 直接获取所以不管
在这里插入图片描述
我们一步一步的来 先进入创建工厂的方法
在这里插入图片描述
在创建bean工厂的时候 我们看到它会一层一层的调用父类的构造方法有许多属性被初始化
我们需要注意下初始化的时候 这三个方法 我们在创建bean的时候通过会通过Aware来填充一些属性 而这个方法可以忽略这些填充的属性
在这里插入图片描述
我们看下一个方法 这个也很简单 就是设置一些属性值 用的时候拿出来判断一下就行了
这里我们需要注意的是 我们可以自定义这两个属性我们可以自己设置这两个属性的值在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

接下来我们看一看最重要的方法 加载beanDefinition到bean工厂中
在这里插入图片描述
同样的这个创建XmlBeanDefinitionReader 也是套娃 一层一层的调用父类的构造方法 初始化了许多属性
我们可以看到传入了bean工厂进去让它帮我们把BeanDefinition装入beanFactory中
下一个方法 设置环境对象 其实环境对象我们早就已经设置好的了 在初始化XmlBeanDefinitionReader的时候 就已经创建好了 我们看一看
在这里插入图片描述
它其实就是将我们电脑的一些环境配置放入属性中
在这里插入图片描述
我么看下一给重要的方法
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
这个set方法只是一个赋值 主要的是后面的资源对象处理器的对象
我们可以看到 它最后创建了两个对象
在这里插入图片描述
什么是dtd什么是xsd那 就是我们spring文件里面引入的一些东西的格式 不用太在意 只需要知道我们一般用xsd就行了
在这里插入图片描述
所以我们直接看xsd文件格式的处理器的创建
我们看到它赋值了一些属性就完成了对象的创建
在这里插入图片描述
我们具体看一看第二个属性到底是什么
在这里插入图片描述
它到底代表者什么哪
我们进入spring-context源码的这个文件夹看一看
在这里插入图片描述
这就是一堆地址的映射文件 本来我们需要从网上下载一些处理我们spring配置文件里面属性的文件 但是有可能在某一些情况下没有网络 有了这个映射地址之后 我们就可以直接通过网址找到本地的地址来获取处理文件 这个很重要 我们后面会用到
下一个又是初始化一些属性 我们就不看了 直接进入下述方法
loadBeanDefinitions(beanDefinitionReader);
我们可以看到它会从我们的reader对象中获取到ConfigLocations和Resources对象
在这里插入图片描述
当然默认Resources对象是没有的 我们一般调用下面的构造方法
在这里插入图片描述
除非我们调用的是这个构造方法 才会对resource赋值
在这里插入图片描述
那么问题又来了 我们什么时候对configLocation对象赋值的 下面的方法就做了这个操作
注意哦 我们当前的方法 是在refresh中调用的里面的方法一层层掉的我们刚刚将的位置的 接着看
在这里插入图片描述
获取到location之后直接reader.loadBeanDefinitions(configLocations);
进入该方法 就是一个for循环遍历每一个地址来一个个加载
在这里插入图片描述
我们继续进入loadBeanDefinitions 又进入了一个小方法 继续走
在这里插入图片描述
我们看到经过一些简单的处理过后 将location放入了getResources进行了处理 不知道还记不记得上面的Resource 不是为空的吗 如果不为空的话 那么我们就应该进入这次的locdBeanDefinitions 跳过了上面的步骤
在这里插入图片描述
我们直接看loadBeanDefinitions 其他的不用太在意 过一下流程就行 又是for循环 我们继续下去看
在这里插入图片描述
我们看到它将我们的resource对象传入了EncodeResource中 我们看一看EncodeResource有什么
在这里插入图片描述
就只是一个简单的赋值 将单独的Resource对象和encoding个charset一起封装成为EncodeResource
在这里插入图片描述
我们接着看封装成对象后执行的方法
在这里插入图片描述
我们可以看到 获得输入流 然后将输入流和Resource对象一起传入新的方法中 其他的不用太在意
就只是看一看当前线程是否处理的时候出现了异常程序直接中断了 做一些保存 我们接着看
在这里插入图片描述
接下来的方法就有意思了 通过输入流获取到Document对象 可能有人会疑惑 为什么要生成Document对象 因为纯字符串的话 我们不太容易进行一些解析或者处理 所以生成Document对象提前帮我们把标签或者其他的进行了区别 具体怎么执行就不属于spring的内容了 接下来将我们获得的Document对象和Resource对象传入进行处理
在这里插入图片描述
我们进入那个我画圈的方法看一下 里面非常重要
我们先看一看createReaderContext 它到底是个什么对象
在这里插入图片描述
我们先看看getNamspaceHandlerResolver方法干了什么
在这里插入图片描述
我们直接进入3中看一看
在这里插入图片描述
我们看一看这个方法 是不是和我们之前设置的那个xsd文件处理的时候赋值的那个东西很相同 他们的值也是非常相似
在这里插入图片描述
我们看看里面到底有什么
在这里插入图片描述
它也是一个映射关系 但是不是文件地址了 而是一个类的位置 这个类到底是用来干什么的那 可以明确的告诉大家 这是用来处理文件中的标签属性的 比如bean中的id属性啊等等
xsd文件只是帮我们将属性区别开来 这里才能处理
在这里插入图片描述
好了我们继续回到注册方法 向下走
在这里插入图片描述
在这里插入图片描述
delegate对象 就是创建一个用于解析的对象 可以处理许多默认没有的在这里插入图片描述
import bean alias beans都是里面默认的
在这里插入图片描述
我们主要看里面没有的怎么处理的 里面默认的就只是少了一些我们的自定义处理而已
在这里插入图片描述
就是我们刚刚看到的DocumentReader里面传入参数时候新建的函数来获取到的
在这里插入图片描述
在这里插入图片描述
我们看一看它怎样获取
在这里插入图片描述
上面方法我们获取到了处理类了我们进入处理方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
得到parse过后 我们正式开始处理工作 我们直接看第一个方法 记得我们之前说的有迷人标签的处理吗 下面的方法就是和它里面默认的bean import等标签处理相同了
在这里插入图片描述
我们可以看到它里面就是从节点里面获取参数 什么参数 就是类似与下面的参数 然后对参数加入到builder对象 最后直接通过builder对象生成B而安Definition对象
在这里插入图片描述

在这里插入图片描述
整个流程我们已经过完了那么 我们可以以直接实现自己定义的标签吗
通过上述的流程我们可以知道 自定义标签有以上几个步骤
1.首先创建Handler对象
2.创建parse对象
3.在META-INF下写一些配置文件

public class MyOwnNamespaceHandler extends NamespaceHandlerSupport {//直接继承该类 重写它的init方法  调用方法注册我们自己的bean  与它的标签名对应
	@Override
	public void init() {
		registerBeanDefinitionParser("user",new UserBeanDefinitionParser());
	}
}

我们发现里面还要实现返回的对象类型 我们就简单的设置一个对象

public class User {
	private String username;
	private String email;
	private String age;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getAge() {
		return age;
	}

	public void setAge(String age) {
		this.age = age;
	}
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {//这里为什么不实现AbstractPropertyLoadingBeanDefinitionParser  spring里面实现的就是这个类  但是因为它里面有许多默认属性处理 我们简单写的不需要


	@Override
	protected Class<?> getBeanClass(Element element) {//返回它需要的对象的类型
		return User.class;
	}

	@Override
	protected void doParse(Element element, BeanDefinitionBuilder builder) {//进行属性值的处理

		String username = element.getAttribute("username");
		String email = element.getAttribute("email");
		String age = element.getAttribute("age");
		if (StringUtils.hasText(username) ) {
			builder.addPropertyValue("username", username);
		}
		if (StringUtils.hasText(email) ) {
			builder.addPropertyValue("email", email);
		}
		if (StringUtils.hasText(age) ) {
			builder.addPropertyValue("age", age);
		}
	}
}

它里面有这些默认的处理 我们不想要 直接继承他 删除super也可以
在这里插入图片描述
下一步 创建配置文件 我们知道我们两次看到的文件都是在META-INF文件下面 我们直接创建两个文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
schemas中装的内容
在这里插入图片描述
handlers装的内容 自己的工程文件名不一样记得改
在这里插入图片描述
我们全部是仿照spring里面的内容写的 但是我们发现一个问题 META-INF/user.xsd文件我们没有啊
没事 我们也仿照它的写 没问题 一定不要写错格式啊 要不然可能会出错 还有 文件必须是.properties类型的 其他类型的读取不了 除了最后一个是xsd 里面targetNamespace和xmlns:tns不一样记得改 和配置文件中的一致

<?xml version="1.0" encoding="UTF-8"?>

<schema xmlns="http://www.w3.org/2001/XMLSchema"
		targetNamespace="http://www.gsx.com/schema/gsx"
		xmlns:tns="http://www.gsx.com/schema/gsx"
		elementFormDefault="qualified">
	<element name="user">
		<complexType>
			<attribute name="id" type="string"></attribute>
			<attribute name="username" type="string"></attribute>
			<attribute name="email" type="string"></attribute>
			<attribute name="age" type="string"></attribute>
		</complexType>
	</element>
</schema>

这下我们通过xsd文件让它可以分辨出我们的对象和它的类型
通过handler读取出来的配置类可以帮我们实现各个属性的处理
接下来我们开始使用
在这里插入图片描述

接下来我们开始使用在这里插入图片描述
结果如下
在这里插入图片描述

标签:String,自定义,beanFactory,对象,spring,public,方法,我们,属性
来源: https://blog.csdn.net/m0_49708063/article/details/121257147

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有