夜譚spring的運行原理

衆所周知,spring最著名的就是依賴注入,閒暇之際我思考spring的運行原理,文中有一問題尚未解決,希望各路高手指點迷津。

下面是我模擬spring的運行原理寫的一個程序,希望對大家有用!

首先跟大家分享框架結構圖:

第一步,創建配置管理器

第二步,創建配置文件

第三步,讀取配置文件

第四步,實例化對象

第五步,注入


下面請大家跟我看一下類文件

BeansConfig的dtd文件

<!ELEMENT beans (bean*)>
<!ELEMENT bean (property*)>
<!ATTLIST bean
	id CDATA #REQUIRED
	class CDATA #REQUIRED>
<!ELEMENT property EMPTY>
<!ATTLIST property
	name CDATA #REQUIRED
	value CDATA ""
	ref CDATA "">
Bean類文件

package com.huan.frame;

import java.util.*;

public class Bean {
	private String id;
	private String className;
	private List<Property> proList = new ArrayList<Property>();
	public void aadProperty(Property property){
		proList.add(property);
	}
	public List<Property> getPropertyList(){
		return proList;
	}
	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;
	}
}
BeanManager類文件
package com.huan.frame;

public class BeanManager {
	public static Object createInstance(String name){
		try {
			return Class.forName(name).newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}
ConfigFile類文件
package com.huan.frame;

import java.util.*;

public class ConfigFile {
	private List<Bean> beanList = new ArrayList<Bean>();
	public void addBean(Bean bean){
		beanList.add(bean);
	}
	public List<Bean> getBean(){
		return beanList;
	}
}
ConfigManager類文件(84行一下這些類反射一直有個問題,希望大家能指點一下)

package com.huan.frame;

import java.io.InputStream;
import java.lang.reflect.*;
import java.util.Iterator;

import org.dom4j.*;
import org.dom4j.io.SAXReader;

public class ConfigManager {
	private ConfigFile config = new ConfigFile();
	
	public ConfigManager(String[] files){
		for (String file : files) {
			read(file);
		}
	}
	
	public void read(String file){
		try {
			if(file ==null || file.isEmpty()) throw new Exception("Spring:配置文件爲空!");
			InputStream is = getClass().getResourceAsStream("/" + file);
			Document doc = new SAXReader().read(is);
			Element root = doc.getRootElement();
			Iterator<Element> beanIt = root.elementIterator("bean");
			Bean bean = null;
			Element beanEl = null,propertyEl = null;
			Iterator<Element> propertyIt = null;
			Property property = null;
			System.out.println("Spring:讀取配置文件");
			while(beanIt.hasNext()){
				bean = new Bean();
				beanEl = beanIt.next();
				bean.setId(beanEl.attributeValue("id"));
				bean.setClassName(beanEl.attributeValue("class"));
				propertyIt = beanEl.elementIterator("property");
				while(propertyIt.hasNext()){
					property = new Property();
					propertyEl = propertyIt.next();
					property.setName(propertyEl.attributeValue("name"));
					property.setValue(propertyEl.attributeValue("value"));
					property.setRef(propertyEl.attributeValue("ref"));
					bean.aadProperty(property);
				}
				config.addBean(bean);
			}
			System.out.println("Spring:讀取配置文件完畢");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public Object getBean(String name){
		Object obj = null;
		try {
			if(name == null || name.isEmpty()) throw new Exception("Spring:bean名爲空!");
			Iterator<Bean> beans = config.getBean().iterator();
			Bean bean = null;
			while(beans.hasNext()){
				bean = beans.next();
				if(name.equals(bean.getId())) break;
				else bean = null;
			}
			if(bean == null) throw new Exception("Spring:bean名未找到!");
			obj = BeanManager.createInstance(bean.getClassName());
			Iterator<Property> propertys = bean.getPropertyList().iterator();
			Property property = null;
			Class clazz = null;
			Method[] methods = null;
			Type[] types = null;
			String[] strs = null;
			Method sure = null;
			while(propertys.hasNext()){
				property = propertys.next();
				clazz = Class.forName(bean.getClassName());
				methods = clazz.getMethods();
				for (Method method : methods) {
					if(method.getName().equals(buildMethodName(property.getName()))){
						if(property.isValue()){
							types = method.getGenericParameterTypes();
							for (Type type : types) {
								strs = type.toString().split(" ");
								if(strs.length == 1){
									if(strs[0].equals("byte")){
										sure = clazz.getMethod(method.getName()
												, Class.forName("java.lang.Byte"));
										sure.invoke(obj, Byte.parseByte(property.getValue()));
									}
									if(strs[0].equals("short")){
										sure = clazz.getMethod(method.getName()
												, Class.forName("java.lang.Short"));
										sure.invoke(obj, Short.parseShort(property.getValue()));
									}
									if(strs[0].equals("int")){
										sure = clazz.getMethod(method.getName()
												, Class.forName("java.lang.Integer"));
										sure.invoke(obj, Integer.parseInt(property.getValue()));
									}
									if(strs[0].equals("long")){
										sure = clazz.getMethod(method.getName()
												, Class.forName("java.lang.Long"));
										sure.invoke(obj, Long.parseLong(property.getValue()));
									}
									if(strs[0].equals("float")){
										sure = clazz.getMethod(method.getName()
												, Class.forName("java.lang.Float"));
										sure.invoke(obj, Float.parseFloat(property.getValue()));
									}
									if(strs[0].equals("double")){
										sure = clazz.getMethod(method.getName()
												, Class.forName("java.lang.Double"));
										sure.invoke(obj, Double.parseDouble(property.getValue()));
									}
									if(strs[0].equals("char")){
										sure = clazz.getMethod(method.getName()
												, Class.forName("java.lang.Character"));
										sure.invoke(obj, property.getValue().charAt(0));
									}
									if(strs[0].equals("boolean")){
										sure = clazz.getMethod(method.getName()
												, Class.forName("java.lang.Boolean"));
										sure.invoke(obj, Boolean.parseBoolean(property.getValue()));
									}
								}else{
									sure = clazz.getMethod(method.getName(), Class.forName(strs[1]));
									sure.invoke(obj, property.getValue());
								}
							}
						}else{
							Object var = getBean(property.getRef());
							sure = clazz.getMethod(method.getName()
									, var.getClass());
							sure.invoke(obj, var);
						}
					}
				}
			}
			return obj;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	public String buildMethodName(String attName){
		try {
			if(attName == null || attName.isEmpty()) 
				throw new Exception("Spring:創建方法的屬性名爲空!");
			return "set" + attName.substring(0,1).toUpperCase() + attName.substring(1);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}
Property類文件
package com.huan.frame;

public class Property {
	private String name;
	private String value;
	private String ref;
	public boolean isValue(){
		if(value.isEmpty())
			return false;
		return true;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}
	public String getRef() {
		return ref;
	}
	public void setRef(String ref) {
		this.ref = ref;
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章