1.spring理解
spring说白了就是一个容器,相当于一个工厂,让一个对象的创建不用new,可以自动生产。它的核心是IOC(反转控制)和DI(依赖注入)这其实就是利用了java中的反射机制。反射其实就是在运行时动态去创建,调用对象。Spring就是在运行时,跟xml Spring的配置文件来动态的创建对象,和调用对象里的方法的 理解了spring的底层原理之后,里面的属性各方面的值就可以直接用Map去存
2.代码实现
2.1 先写一个自定义接口,里面写一个getBean(int id)
2.2在写一个类去实现自定义接口并在这个类里面的构造方法写入解析代码(采用jdom解析原理),代码如下
2.3自己写一个application.xml去测试
public SelfClassPathXmlApplicationContext(String xmlPath){
//1. 读取 xmlpath 文件
SAXBuilder sb = new SAXBuilder(); //jdom才底层采用sax解析方式
// 2. 解析 xml -> dom -> 一次性加载整棵树,以dom模型解析, sax -》 流的方式加载数据,以事件的方式来解析xml
InputStream iis = this.getClass().getClassLoader().getResourceAsStream(xmlPath);
Document doc = sb.build(iis);
Element rootElement = doc.getRootElement();
//3.得到所有的bean,是list列表
List<Element> list = rootElement.getChildren();
//4.循环这个list列表
for (Element ele : list) {
//5.取出id,class
String id = ele.getAttributeValue("id");
String classPath = ele.getAttributeValue("class");
//6.以反射方式根据class值来创建一个object对象(调用了这个对象的无参构造方法)
Object obj = Class.forName(classPath).newInstance(); //无参构造方法
//7. beans.put(id.obj)
beans.put(id, obj);取 xmlpath 文件
//8.查看这个bean下是否有子节点 property
//9.如果有,则循环所有的子节点,取出name value ref
for (Element proElement :(List<Element>)ele.getChildren()) {
String name = proElement.getAttributeValue("name");
String value = proElement.getAttributeValue("value");
String ref = proElement.getAttributeValue("ref");
//取出对应的setXxx()方法 set + name 首字母大写
String methodName = "set"+name.substring(0, 1).toUpperCase()+name.substring(1);
//从Class中找到这个方法
Method m = findMethod(methodName,classPath);
if(m==null) {
continue;
}
//m就是一个setXxx()方法,他只有一个参数,但getParameters()会取出多个参数
String typename = m.getParameters()[0].getType().getName();
// setSid 的参数类型为:java.lang.reflect.Parameter
System.out.println(m.getName()+"的参数类型为:" +typename);
//10.判断是value吗?
if(value!=null) {
//是,则在class对象找set Name这个方法
//如有这个setXxx()方法 则激活
if("int".equals(typename) || "java.lang.Integer".equals(typename)) {
//parseInt() 函数可解析一个字符串,并返回一个整数
int v = Integer.parseInt(value);
m.invoke(obj, v);
}else if("float".equals(typename) || "java.lang.Float".equals(typename)) {
float v = Float.parseFloat(value);
m.invoke(obj, v);
}else if("double".equals(typename) || "java.lang.Double".equals(typename)) {
double v = Double.parseDouble(value);
m.invoke(obj, v);
}else {
m.invoke(obj, value);
}
}else if(ref!=null) { //11.判断ref不为空
//TODO:
Object toInjectObject = beans.get(ref);
System.out.println("toInjectObject==>" +toInjectObject);
m.invoke(obj, toInjectObject);
}
}
}
//写一个方法去循环放射对象中的所有方法
private Method findMethod(String methodName,String classPath) throws ClassNotFoundException {
Class c = Class.forName(classPath);
Method[] ms = c.getMethods();
for (Method m : ms) {
if(m.getName().equals(methodName)) {
return m;
}
}
return null;
}