spring xml文件注册bean信息
亿点点小细节之xml文件解析
xml文件解析 是 spring的亿点点小细节之一。
核心目的就是将文件内容转为 BeanDefinition对象,并注册到BeanFactory中
学校小故事
学校小故事源链接: 学校小故事。
学校 | spring |
---|---|
学校人员信息库 | DefaultListableBeanFactory |
人员 | bean |
人员信息 | BeanDefinition |
最初信息规范版本:xml文件规范
学校管理局<spring开发人员>早期定义的信息完善规范,配置较为繁琐。
定义*.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
在beans中创建 bean标签
bean 的基本标签
<!--
bean: spring的开发人员定义标签
属性:id<>
class<交给spring管理的 bean的全路径>
scope<作用域。singleton单例;prototype原型/多例。默认为单例>
子标签:property<bean中class的构造方法参数> value和ref二选一
子标签属性:name<构造方法中的参数名>
ref<其他bean的id>
value<基本数据类型>
-->
<bean id="apple" class="com.spring.cloud.moduletest.simple.Apple" autowire="byName">
<property name="banana" ref="banana"/>
</bean>
xml文件解析
xml文件内容解析
refresh方法源头调用:
AbstractApplicationContext类中的
obtainFreshBeanFactory<创建BeanFactory>方法
XmlWebApplicationContext类中的
loadBeanDefinitions方法<完成XmlBeanDefinitionReader解析器初始化,并调用解析方法>。
doLoadDocument方法<完成读取配置文件,将配置文件内容转为Document对象>
DefaultBeanDefinitionDocumentReader类中
doRegisterBeanDefinitions方法<解析Document对象,转为BeanDefinition>
在此方法中包含以下流程
1、检查beans中的url是否存在http://www.springframework.org/schema/beans,不存在直接返回报错<找不到元素 'beans' 的声明>。
if (this.delegate.isDefaultNamespace(root)) {}
2、Document解析模板方法。
// 为子类扩展而存在,bean中方法为空方法
preProcessXml(root);
// 解析Document并注册到BeanFactory。
parseBeanDefinitions(root, this.delegate);
// 为子类扩展而存在,bean中方法为空方法
postProcessXml(root);
3、DefaultBeanDefinitionDocumentReader可以解析以下标签
import、alias、bean、beans
存在三种解析方法
importBeanDefinitionResource、processAliasRegistration、processBeanDefinition
bean的不常用标签
平时开发时,基本用不上。使用时搜索查一下就好,21世纪一般使用配置类检索spring管理的对象/方法,了解即可。
bean: spring的开发人员定义标签
属性:class<交给spring管理的 bean的全路径>
abstract<抽象方法>
lazy-init<懒加载,不会自动实例化,在使用时实例化>
depends-on<需要先创建依赖bean,再将当前bean实例化>
scope<作用域。singleton单例 prototype原型/多例>
primary<多个同类型bean,其他bean主要引用primary为true的bean>
init-method<初始化方法>
destroy-method<销毁方法>
factory-method<工厂方法>
factory-bean<实现FactoryBean接口的bean类,使用另外一种创建对象方式>
子标签:constructor-arg<构造方法中的参数>
子标签属性:index<构造方法中参数下标,从0开始>
value<第 index 参数值>
子标签:property<bean中class的构造方法参数> value和ref二选一
子标签属性:name<构造方法中的参数名>
ref<其他bean的id>
value<基本数据类型>
自定义xml文件解析过程<炫技使用,不推荐>
21世纪的开发人员还会有人使用xml文件声明spring管理bean?不会吧😲
0、写代码之前
人类获取知识历程一般分为三个阶段:模仿,学习,创造。
对源码没有足够理解之前,请参考源码完成实现功能,再迭代进步。
1、创建xml标签处理器Handler
CustomLabelHandler参考ContextNamespaceHandler.class完成
public class CustomLabelHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("student", new CustomLabelParser());
}
}
2、创建xml标签解析器Parser
CustomLabelParser参考PropertyOverrideBeanDefinitionParser.class完成
public class CustomLabelParser extends AbstractSingleBeanDefinitionParser {
@Override
protected Class<?> getBeanClass(Element element) {
return Student.class;
}
@Override
protected void doParse(Element element, BeanDefinitionBuilder builder) {
if (element.hasAttribute("userName")) {
builder.addPropertyValue("userName", element.getAttribute("userName"));
}
if (element.hasAttribute("password")) {
builder.addPropertyValue("password", element.getAttribute("password"));
}
}
}
3、spring.handlers文件中注册handler
META-INF文件夹下创建spring.handlers文件
# *** 请自定义替换
http\://www.***.org/schema/student=*.*.*.*.CustomLabelHandler
4、spring.schemas文件声明xsd文件位置
META-INF文件夹下创建spring.schemas文件
# *** 请自定义替换
http\://www.***.org/schema/student.xsd=META-INF/student.xsd
5、xsd中规范 标签中属性
META-INF文件夹下创建student.xsd文件
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.zhaojiafeng.org/schema/student"
xmlns:tns="http://www.zhaojiafeng.org/schema/student"
elementFormDefault="qualified">
<element name="student">
<complexType>
<attribute name="id" type="string"/>
<attribute name="userName" type="string"/>
<attribute name="password" type="string"/>
</complexType>
</element>
</schema>
6、验证自定义标签
自定义启动xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:abc="http://www.***.org/schema/student"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.***.org/schema/student
http://www.***.org/schema/student.xsd">
<!--- xmlns:abc 标签内属性和xsd文件中声明属性一致 -->
<abc:student id="student" userName="userName456" password="password123"/>
</beans>
7、测试类验证附结果
验证测试类
public static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("customLabel/customLabel.xml");
Student bean = (Student) ac.getBean("student");
System.out.println(bean);
System.out.println(bean.getUserName());
System.out.println(bean.getPassword());
}
结果:
16:00:47.760 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1517365b
16:00:47.913 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 1 bean definitions from class path resource [customLabel/customLabel.xml]
16:00:47.937 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'student'
com.spring.cloud.moduletest.customLabel.Student@710726a3
userName456
password123
尾言
刚刚开始发布技术分享文章,如有引用,请声明引用地址。