1.实现技术:dom4j解析xml,反射
2.需要的jar包:dom4j-1.6.1.jar,jaxen-1.1.6.jar
public class SecondSpring {
//此结合存储是spring.xml中的所有信息private Map<String,BeanDefinition> beanDefinitions=new HashMap<String,BeanDefinition>();
//此集合中存储的是spring.xml中的bean节点的对象
public Map<String,Object> singletons=new HashMap<String,Object>();
public SecondSpring(){
}
public SecondSpring(String fileName){
readXml(fileName);
instanceObject();
injectObject();
}
/**
* 如果有property节点,取出name的值
* 把第一字母大写,前面拼装set,
* 把拼装的字符串做方法的名字去类寻找有没有对应setterfangfa
* 如果有就调用setter方法,并把容器(singletons)中的对象注入进去
*/
private void injectObject(){
for(BeanDefinition bd: beanDefinitions.values()){
Object obj=singletons.get(bd.getId());
for(PropertyDefinition pd:bd.getProperties().values()){
String name=pd.getName();//userDao
String ref=pd.getRef();
String setterMethodName=
"set"
+name.substring(0,1).toUpperCase()
+name.substring(1);//setUserDao
Class clazz=obj.getClass();
Method[] methods=clazz.getDeclaredMethods();
for(Method method:methods){
if(method.getName().equals(setterMethodName)){
Object value=singletons.get(ref);
//说明找到setter方法
try {
method.invoke(obj, value);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
/**
* 循环遍历beanDefinitions,
* 取出class,并Class.forName("").newInstance();
*/
private void instanceObject(){
try {
for(BeanDefinition bd : beanDefinitions.values()){
String className=bd.getClassName();
Object obj=Class.forName(className).newInstance();
singletons.put(bd.getId(), obj);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 加载和解析spring的xml文件
* @param fileName
*/
private void readXml(String fileName){
SAXReader saxReader=new SAXReader();
Document document=null;
try{
URL xmlPath=SecondSpring.class
.getClassLoader()
.getResource(fileName);
document=saxReader.read(xmlPath);
//准备开始解析xml文档
Map<String,String> nsMap=new HashMap<String,String>();
nsMap.put("ns","http://www.springframework.org/schema/beans");
//构建xpath路径 /beans/bean
XPath xsub=document.createXPath("//ns:beans/ns:bean");
xsub.setNamespaceURIs(nsMap);
//从xpath路径中解析出所有的bean节点
List<Element> beans=xsub.selectNodes(document);
for(Element element : beans){
String id=element.attributeValue("id");
String className=element.attributeValue("class");
BeanDefinition beanDefinition=new BeanDefinition();
beanDefinition.setId(id);
beanDefinition.setClassName(className);
//构建xpath 解析/beans/bean/property
XPath propertySub=element.createXPath("ns:property");
propertySub.setNamespaceURIs(nsMap);
//解析property节点
List<Element> properties=propertySub.selectNodes(element);
for(Element property : properties){
String propertyName=property.attributeValue("name");
String PropertyRef=property.attributeValue("ref");
PropertyDefinition propertyDefinition=new PropertyDefinition();
propertyDefinition.setName(propertyName);
propertyDefinition.setRef(PropertyRef);
beanDefinition.getProperties().put(propertyName, propertyDefinition);
}
beanDefinitions.put(id, beanDefinition);
}
}catch(Exception e){
e.printStackTrace();
}
}
public Object getBean(String key){
return singletons.get(key);
}
3.需要建立一个BeaDefinition来储存bean节点对象,该类中属性就是bean节点中的属性值
public class BeanDefinition {
private String id;
private String className;
private Map<String,PropertyDefinition> properties=new HashMap<String,PropertyDefinition>();
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 Map<String, PropertyDefinition> getProperties() {
return properties;
}
public void setProperties(Map<String, PropertyDefinition> properties) {
this.properties = properties;
}
}
4.创建一个property对象,储存property节点
public class PropertyDefinition {
private String name;
private String ref;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
}