Java通过DOM解析假装实现Spring中Bean注入

通过DOM解析假装实现Spring中Bean注入

一、案例需求

通过反射的形式去创建对象,只要通过传入xml配置,我们使用DOM解析xml的方式,去读取数据,根据数据去创建对象和简单属性赋值!该案例在于更好的理解Spring中的IOC容器
本文参考博文:XML解析之DOM解析详解

二、步骤结解析

  1. 创建实体类
  2. 创建application.xml文件
  3. 解析xml文件
  4. 根据反射去创建bean对象
  5. 将xml配置的中property节点的数据赋给创建好bean
  6. 测试

三、代码实现

1. 创建实体类

该实体类的set方法都要是Object,因为我们不知到从xml读取的文件是什么类型!

public class Student {
	private int sid;
	private String name;
	private String sex;
	public Student() {
		super();
	}
	public Student(int sid, String name, String sex) {
		super();
		this.sid = sid;
		this.name = name;
		this.sex = sex;
	}
	// 注意:所有set方法的参收都要是Object类型的,这里需要强转一下
	public int getSid() {
		return sid;
	}
	public void setSid(Object sid) {
		this.sid = Integer.parseInt(sid.toString());
	}
	public String getName() {
		return name;
	}
	public void setName(Object name) {
		this.name = (String) name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(Object sex) {
		this.sex = (String) sex;
	}
	@Override
	public String toString() {
		return "Student [sid=" + sid + ", name=" + name + ", sex=" + sex + "]";
	}
	
}
2. 创建ApplicationContext.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans>
   <bean name="student" class="model.Student">
		<property name="sid" value="001"></property>
		<property name="name" value="name"></property>
		<property name="sex"  value=""></property>
   </bean>
</beans>
3. 解析xml文件、创建对象、并给对象赋值

该类通过注释进行一步步解析,可以仔细看一下注释!

public class MyApplicationContext{
	// 使用多线程赋值的话建议使用ConcurrentHashMap
	//	private Map<String,Object> beansHolder = new ConcurrentHashMap<String, Object>();
	private Map<String,Object> beansMap = new HashMap<String, Object>();
	private String xmlPath;
	
	public MyApplicationContext(String xmlPath) {
		this.xmlPath = xmlPath;
		analysisXML();
	}
	// DOM解析xml
	public void analysisXML() {
		// 找了一个工厂
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		try {
			// 工厂里的一个工人
			DocumentBuilder buider = factory.newDocumentBuilder();
			// 工人去读取xml文件 ,然后得到了一个读取到的文件
			Document document = buider.parse(xmlPath);
			// 读取所有bean节点
			NodeList nodeBean = document.getElementsByTagName("bean");
			// 循环遍历nodeBean
			for(int i = 0; i < nodeBean.getLength();i++) {
				// 得到所有bean属性
				NamedNodeMap namedNodeMap = nodeBean.item(i).getAttributes();
				// 获取bean节点
				Element element = (Element)nodeBean.item(i);
				// 获取bean节点下所有property元素
				NodeList childNodes = element.getElementsByTagName("property");
				// 将获取到的bean所有属性和bean节点下所有property元素传递到创建bean方法中继续使用
				createBean(namedNodeMap,childNodes);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	// 创建bean
	public void createBean(NamedNodeMap namedNodeMap,NodeList childNodes) {
		String className = null; // bean节点中的name属性值
		String class_val = null; // bean节点中的class属性值
		// 遍历bean的所有属性
		for(int i = 0; i < namedNodeMap.getLength();i++) {
			Node node = namedNodeMap.item(i);
			// 取出name属性值
			if("name".equalsIgnoreCase(node.getNodeName())) {
				className = node.getNodeValue();
			}
			// 取出class属性值
			if("class".equals(node.getNodeName())){
				class_val = node.getNodeValue();
			}
			// 判断二者都不为空
			if(!"".equals(className) && !"".equals(class_val)) {
				// 去创建bean,并存入map集合
				setBean(className,class_val);
			}else {
				System.out.println("参数为空!");
			}
		}
		// 属性赋值(bean节点下所有property元素,bean的class属性值,bean的name属性值)
		setProperty(childNodes,class_val,className);
	}
	// 注入属性值
	public void setProperty(NodeList childNodes,String class_val,String className) {
		String name_val = null;  //property元素中的name属性值
		Object value_val = null; //property元素中的value属性值
		// 遍历所有property元素
		for(int i = 0; i < childNodes.getLength();i++) {
			// 获取每个property所有属性
			NamedNodeMap attributes = childNodes.item(i).getAttributes();
			// 遍历property的所有属性
			for(int j = 0; j < attributes.getLength();j++) {
				// 得到一个属性节点
			    Node node = attributes.item(j);
				if(node!= null) {
					// 得到name的值
					if("name".equals(node.getNodeName())) {
						name_val = node.getNodeValue();
					}
					// 得到value的值
					if("value".equals(node.getNodeName())){
						value_val = node.getNodeValue();
					}
				}
			} 
			try {
				// 根据bean的class属性值,获取指定类的构造器
				Class<?> clazz = Class.forName(class_val);
				// 去查找set方法,传入参数类型
				Method method = clazz.getMethod("set"+toFirst(name_val),Object.class);
				// 然后去执行set方法,指定实体类,传入该方法所需的参数
				method.invoke(beansMap.get(className),value_val);
				} catch (Exception e) {	
					e.printStackTrace();
				}
		}
	 }
    // 首字母大写
	public String toFirst(String str) {
		if(str!=null&&str.length()>0){
			str=str.substring(0, 1).toUpperCase() + str.substring(1);
		}
		return str;
	}
	// 注入bean
	public void setBean(String beanNname,String clazzPath) {
		try {
			// 通过反射创建bena对象
			Object obj = Class.forName(clazzPath).newInstance();
			// 将创建的bean存入map集合
			beansMap.put(beanNname,obj);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	//  获取bean对象
	public Object getBean(String beanName) {
		return beansMap.get(beanName);
	}

}

3. 测试

public class MainTest {
public static void main(String[] args) {
	MyApplicationContext context  = new MyApplicationContext("src/application.xml");
	Student student = (Student) context.getBean("student");
	System.out.println(student.toString());
  }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java,我们可以使用节点解析器来解析XML文件。以下是一个简单的示例,演示如何使用节点解析器来解析XML文件: ``` import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.w3c.dom.Node; import org.w3c.dom.Element; import java.io.File; public class XMLParser { public static void main(String[] args) { try { File inputFile = new File("input.xml"); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(inputFile); doc.getDocumentElement().normalize(); System.out.println("Root element :" + doc.getDocumentElement().getNodeName()); NodeList nList = doc.getElementsByTagName("student"); System.out.println("----------------------------"); for (int temp = 0; temp < nList.getLength(); temp++) { Node nNode = nList.item(temp); System.out.println("\nCurrent Element :" + nNode.getNodeName()); if (nNode.getNodeType() == Node.ELEMENT_NODE) { Element eElement = (Element) nNode; System.out.println("Student roll no : " + eElement.getAttribute("rollno")); System.out.println("First Name : " + eElement.getElementsByTagName("firstname") .item(0).getTextContent()); System.out.println("Last Name : " + eElement.getElementsByTagName("lastname") .item(0).getTextContent()); System.out.println("Nick Name : " + eElement.getElementsByTagName("nickname") .item(0).getTextContent()); System.out.println("Marks : " + eElement.getElementsByTagName("marks") .item(0).getTextContent()); } } } catch (Exception e) { e.printStackTrace(); } } } ``` 在此示例,我们使用了Java内置的DocumentBuilder和Document类来解析XML文件。我们首先将XML文件加载到Document对象,然后使用getNodeName()方法获取根元素的名称。接下来,我们使用getElementsByTagName()方法获取所有名为“student”的元素,并遍历它们以获取其子元素的值。最后,我们使用getTextContent()方法获取每个元素的文本内容。 请注意,此示例仅适用于简单的XML文件。对于更复杂的XML文件,您可能需要更多的代码来处理嵌套元素和属性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值