众所周知,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;
}
}