大致思路
1.通过类路径读取配置文件beans.xml(IO),获取流对象
2.解析流对象(读取xml文件中的内容)
3.将XML文件中的bean标签信息封装到BeanDefinition对象
4.多个bean,再将BeanDefinition封装到map
5.基于xml配置构建对象实例,并存储到instanceMap
6.定义getBean方法,对外提供访问实例的方式
各类包~
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
//>>调用类加载器从类路径读取文件
//>>创建parse方法解析IO流
public class ClassPathXmlApplicationContext {
private Map<String,BeanDefinition> beanMap=
new HashMap<>();
private Map<String,Object> instanceMap=
new HashMap<>();
public ClassPathXmlApplicationContext(
String file) throws Exception{
InputStream in=
this.getClass().getClassLoader()
.getResourceAsStream(file);
parse(in);
}
//>>解析xml,借助JAVA中自带的API进行解析(parse方法的实现)
private void parse(InputStream in)throws Exception{
DocumentBuilderFactory factory=
DocumentBuilderFactory.newInstance();
DocumentBuilder builder=
factory.newDocumentBuilder();
Document doc=builder.parse(in);
processDocument(doc);
}
//>>读取bean元素中的属性并将其封装到BeanDefinition对象
private BeanDefinition processBeanAttrs(NamedNodeMap nMap) {
BeanDefinition bd=new BeanDefinition();
for(int j=0;j<nMap.getLength();j++){
Node attrNode=nMap.item(j);
String nodeName=attrNode.getNodeName();
if(nodeName.equalsIgnoreCase("id")){
bd.setId(attrNode.getNodeValue());
}else if(nodeName.equalsIgnoreCase("class")){
bd.setClassName(attrNode.getNodeValue());
}else if(nodeName.equalsIgnoreCase("lazy")){
bd.setLazy(Boolean.valueOf(attrNode.getNodeValue()));
}
}
return bd;
}
//>>基于反射技术构建类的实例对象
private Object newInstance(String className)throws Exception{
Class<?> cls=Class.forName(className);
Constructor<?> con=cls.getDeclaredConstructor();
con.setAccessible(true);
Object obj=con.newInstance();
return obj;
}
//>>提供getBean();从容器获取对象实例
@SuppressWarnings("unchecked")
public <T>T getBean(String id,Class<T> cls){
Object obj=instanceMap.get(id);
if(obj!=null)return (T)obj;
BeanDefinition bd=beanMap.get(id);
try{
obj=newInstance(bd.getClassName());
instanceMap.put(bd.getId(), obj);
}catch(Exception e){e.getMessage();};
return (T)obj;
}
}
最后附上BeanDifinition实体类代码
public class BeanDefinition {
private String id;
private String className;
private Boolean lazy=false;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public Boolean getLazy() {
return lazy;
}
public void setLazy(Boolean lazy) {
this.lazy = lazy;
}
@Override
public String toString() {
return "BeanDefinition [id=" + id + ", className=" + className + ", lazy=" + lazy + "]";
}
}
以及测试类
import java.util.Date;
public class TestSpring01 {
public static void main(String[] args)
throws Exception{
ClassPathXmlApplicationContext ctx=
new ClassPathXmlApplicationContext(
"beans.xml");
Date date=ctx.getBean("date", Date.class);
System.out.println(date);
Configuration c=
ctx.getBean("cfg", Configuration.class);
}
}