手写一个spring工厂

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>

猜你喜欢

转载自blog.csdn.net/qq_42445333/article/details/89525803