DefaultBeanFactory.java
package com.java.spring;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
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;
public class DefaultBeanFactory {
/**通过此map存储配置文件中的所有bean信息
* 话外音:工厂中的原材料
* */
private Map<String, BeanDefinition> beanMap = new ConcurrentHashMap<>();
/**通过此map存储实例对象
* 话外音:工厂中基于原材料创建的产品
* */
private Map<String, Object> instanceMap = new ConcurrentHashMap<String, Object>();
public DefaultBeanFactory(String cfgFile) {
//1.获取文件对应的流对象
InputStream in = ClassLoader.getSystemResourceAsStream(cfgFile);
//2.处理流对象
handleStream(in);
}
/**处理流中数据*/
private void handleStream(InputStream in) {
try {
//1.构建一个解析器对象(DocumentBuilder)
DocumentBuilder builder =
DocumentBuilderFactory
.newInstance()//工厂
.newDocumentBuilder();//解析器
//2.解析流对象
Document doc = builder.parse(in);
//3.处理document对象(通过此对象可以获取文件中节点信息)
handleDocument(doc);
}catch(Exception e) {
e.printStackTrace();
}
}
/**处理document对象*/
private void handleDocument(Document doc) {
//1.获取所有bean元素
NodeList list =
doc.getElementsByTagName("bean");
//2.迭代bean元素
for(int i=0;i<list.getLength();i++) {
//2.1获取i对应元素(node)
Node node=list.item(i);
//2.2处理Node对象
BeanDefinition bd=handleNode(node);
//2.3将Bean的定义信息存储到map
beanMap.put(bd.getId(),bd);
//2.4假如此bean中的lazy属性为false则创建实例存map
}
}
private BeanDefinition handleNode(Node node) {
//1.构建BeanDefinition对象
BeanDefinition bd=new BeanDefinition();
//2.获取Node节点中相关属性的值
NamedNodeMap attrs=node.getAttributes();
String id=attrs.getNamedItem("id").getNodeValue();
String targetCls=attrs.getNamedItem("class").getNodeValue();
String lazy=attrs.getNamedItem("lazy").getNodeValue();
//3.将数据封装到BeanDefinition对象
bd.setId(id);
bd.setTargetClass(targetCls);
bd.setLazy(Boolean.valueOf(lazy));
return bd;
}
/**创建类的实例对象*/
private Object newInstance(Class<?> cls) {
try {
Constructor<?> con=cls.getDeclaredConstructor();
if(!con.isAccessible())
con.setAccessible(true);
return con.newInstance();
}catch(Exception e) {
e.printStackTrace();
return null;
}
}
/**获取类的实例对象*/
public <T>T getObject(String key,Class<T> cls){
//0.对key和class进行校验
//1)校验key是否存在
if(!beanMap.containsKey(key))
throw new RuntimeException("no such key in bean map");
//2)校验类型对应的资源是否存在
BeanDefinition bd=beanMap.get(key);
if(!bd.getTargetClass().equals(cls.getName()))
throw new RuntimeException("no such bean class");
//1.从instanceMap中取
Object obj=instanceMap.get(key);
if(obj==null) {
obj=newInstance(cls);
instanceMap.put(key, obj);
}
//2.返回实例对象
return (T)obj;
}
public static void main(String[] args) {
DefaultBeanFactory factory=
new DefaultBeanFactory("spring-configs.xml");
Object obj1=factory.getObject("obj", Object.class);
Object obj2=factory.getObject("obj", Object.class);
System.out.println(obj1==obj2);
}
}
BeanDefinition.java
package com.java.spring;
/**
* 值对象-VO:(Value Object)
* 通过此对象封装spring-configs.xml文件中定义的的<bean>元素信息
*
*/
public class BeanDefinition {
private String id;
private String targetClass;
private boolean lazy;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTargetClass() {
return targetClass;
}
public void setTargetClass(String targetClass) {
this.targetClass = targetClass;
}
public boolean isLazy() {
return lazy;
}
public void setLazy(boolean lazy) {
this.lazy = lazy;
}
@Override
public String toString() {
return "BeanDefinition [id=" + id + ", targetClass=" + targetClass + ", lazy=" + lazy + "]";
}
}
spring-configs.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="obj" class="java.long.Object" lazy="true"/>
<bean id="data" class="java.util.Date" lazy="true"/>
</beans>