spring系列(六):springioc: 完全模拟springioc,手工模拟

14 模拟springioc

14.1 创建java项目

14.2 创建实体类

public class Student   implements Serializable{
	{
		System.out.println("构造代码块");
	}
	private Integer sid;
	private String sname;
	private Integer sage;
	private Boolean sdy;
	private Float score;
	private Teacher teacher;
    ...
}
public class Teacher implements Serializable{
	private Integer tid;
	private String tname;
	private String tsex;
    ...
}

14.3 创建核心配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans>
	<bean id="stu1" class="com.zhiyou100.test01.Student"> 
	     <property name="sid" value="1001"/>
	     <property name="sname" value="韩梅梅"/>
	     <property name="sage" value="19"/>
	     <property name="sdy" value="true"/>
	     <property name="score" value="11.6"/>
	</bean>
	<bean id="stu2" class="com.zhiyou100.test01.Student"> 
	     <constructor-arg name="sid" value="1002"/>
	     <constructor-arg name="sname" value="韩寒"/>
	     <constructor-arg name="sage" value="19"/>
	     <constructor-arg name="sdy" value="false"/>
	     <constructor-arg name="score" value="33.5"/>
	</bean>
	<bean id="stu3" class="com.zhiyou100.test01.Student"> 
	     <property name="sid" value="1001"/>
	     <property name="sname" value="韩梅梅"/>
	     <property name="sage" value="19"/>
	     <property name="sdy" value="true"/>
	     <property name="score" value="11.6"/>
	     <property name="teacher" ref="tea1"/>
	</bean>
	<bean id="tea1" class="com.zhiyou100.test01.Teacher" >
	    <property name="tid" value="1002"/>
	    <property name="tname" value="高老师"/>
	    <property name="tsex" value=""/>
	</bean>
</beans>

14.4 创建类模拟ClassPathXmlApplicationContext

方法:1 构造方法::加载核心配置文件
方法:2 getBean方法:根据bean的id获取对象
方法:3 close方法:释放资源销毁对象
package com.zhiyou100.test01;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class MyClassPathXmlApplicationContext {
	private Map<String, Object> mapBeans=new HashMap<String, Object>();
	private InputStream in;
	private Document doc;
	public MyClassPathXmlApplicationContext(String fileName){
		try {
			in=new FileInputStream(new File("src/"+fileName));
			doc=Utils.xml2Doc(in);
			//读取xml中所有的bean标签 创建对象
			init();
		} catch (Exception e) {
			throw new RuntimeException(e);
		} 
		
	}
	private void init()throws Exception{
		//获取所有的bean标签
		NodeList beans=doc.getElementsByTagName("bean");
		//遍历
		for (int i = 0; i < beans.getLength(); i++) {
			Element beanEle=(Element)beans.item(i);
			//获取baen标签的id属性
			String id=beanEle.getAttribute("id");
			//获取baen标签的class属性
			String className=beanEle.getAttribute("class");
			//创建对象
			Class cla=Class.forName(className);
			Object obj=null;
			//判断当前bean标签下是否有constructor-arg子标签
			NodeList conZiList=beanEle.getElementsByTagName("constructor-arg");
			if(conZiList==null||conZiList.getLength()==0){
				obj=cla.newInstance();
				//获取所有的property子标签
				NodeList proZiList=beanEle.getElementsByTagName("property");
				//遍历property子标签
				for (int j = 0; j < proZiList.getLength(); j++) {
					Element proEle=(Element)proZiList.item(j);
					//获取name和value属性
					String name=proEle.getAttribute("name");
					String value=proEle.getAttribute("value");
					//获取字段对象
					Field field=cla.getDeclaredField(name);
					field.setAccessible(true);
					if(value!=null&&!value.isEmpty()){
						field.set(obj, Utils.changeType(value, field.getType()));
					}else{//赋值是通过ref
						String ref=proEle.getAttribute("ref");
						field.set(obj, mapBeans.get(ref));
					}
				}
			}else{
				//定义一个数组装构造方法的参数类型
				Class[] argsTypes=new Class[conZiList.getLength()];//记录构造方法的参数列表的类型
				Field[] fieldArr=new Field[conZiList.getLength()];//记录构造方法的参数列表属性
				String[] valueStrArr=new String[conZiList.getLength()];//记录构造方法的参数列表的字符串值
				Object[] valueObjArr=new Object[conZiList.getLength()];//记录构造方法的参数列表的值
				//遍历所有的constructor-arg子标签
				for (int j = 0; j <conZiList.getLength(); j++) {
					//获取constructor-arg子标签
					Element conZi=(Element)conZiList.item(j);
					//获取其name属性和value属性
					fieldArr[j]=cla.getDeclaredField(conZi.getAttribute("name"));
					valueStrArr[j]=conZi.getAttribute("value");
					valueObjArr[j]=Utils.changeType(valueStrArr[j], fieldArr[j].getType());
					argsTypes[j]=fieldArr[j].getType();
				}
				//通过构造方法给属性赋值的
				Constructor constructor=cla.getDeclaredConstructor(argsTypes);
				constructor.setAccessible(true);
				obj=constructor.newInstance(valueObjArr);
			}
			mapBeans.put(id, obj);
		}
	}
	public void close(){
		try {
			in.close();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	public Object getBean(String name){return mapBeans.get(name);}

}

14.5 测试

//1 创建springcontext对象 加载核心配置文件
MyClassPathXmlApplicationContext context=
    new MyClassPathXmlApplicationContext("com/zhiyou100/test01/spring_config.xml");
//	    //2 获取bean对象
Student s11=(Student)context.getBean("stu3");
System.out.println(s11);
//3 关闭容器
context.close();

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值