模拟spring框架注入实现原理

来源:互联网 发布:网络翻唱歌手娄艺飞 编辑:程序博客网 时间:2024/05/21 10:01

这个我是参见了别人的一些东西,不是原创!

定义一些抽象的方法:

package com.huxin.springinject.dao;public interface Person {    public void save();    public void useAxe();}

 

package com.huxin.springinject.dao;public interface Axe {   public void  chop();   }


实现的一些方法:

package com.huxin.springinject.dao.impl;import com.huxin.springinject.dao.Axe;import com.huxin.springinject.dao.Person;public class Chinese implements Person {private Axe axe;public Axe getAxe() {return axe;}public void setAxe(Axe axe) {this.axe = axe;}public void save() {        System.out.println("保存人的方法");}public void useAxe(){axe.chop();}}


 

package com.huxin.springinject.dao.impl;import com.huxin.springinject.dao.Axe;public class StoneAxe implements Axe {@Overridepublic void chop() {   System.out.println("铁斧头砍柴真慢");}}


这里是关键spring框架模拟的实现的一些原理!!!

package junit.test;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.lang.reflect.Method;import java.net.URL;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import org.apache.commons.beanutils.ConvertUtils;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.XPath;import org.dom4j.io.SAXReader;public class ApplicationContext {     List<BeanInformation> beansInformation = new ArrayList<BeanInformation>();     Map<String,Object> singleton = new HashMap<String,Object>();               public ApplicationContext(){};     public ApplicationContext(String filename){     readXml(filename);     initBean();     this.injectObject();     }     public void readXml(String filename){     SAXReader saxReader = new SAXReader();     Document document = null;     try{         //使用反射机制,通过文件名加载文件路径     URL xmlPath = this.getClass().getClassLoader().getResource(filename);          //通过文件路径获得这个文件的document对象     document = saxReader.read(xmlPath);          Map<String,String> nsMap = new HashMap<String,String>();          nsMap.put("ns","http://www.springframework.org/schema/beans");//加入命名空间                    XPath xsub = document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径          xsub.setNamespaceURIs(nsMap);//设置命名空间         //获得所有路径下的节点     List<Element> beans = xsub.selectNodes(document);//获取文档下所有bean节点     for(Element element : beans){     System.out.println(element.attributeValue("id"));     System.out.println(element.attributeValue("class"));          BeanInformation beanInformation = new BeanInformation();     beanInformation.setId(element.attributeValue("id"));     beanInformation.setName(element.attributeValue("class"));          XPath xref = element.createXPath("ns:property");//创建properties查询路径     xref.setNamespaceURIs(nsMap);//设置命名空间          List<Element> propertys = xref.selectNodes(element);     for(Element property : propertys){     PropertyInformation propertyInformation = new PropertyInformation();     propertyInformation.setName(property.attributeValue("name"));     propertyInformation.setRef(property.attributeValue("ref"));     propertyInformation.setValue(property.attributeValue("value"));     beanInformation.getPropertyInformation().add(propertyInformation);     }     beansInformation.add(beanInformation);     }         } catch(Exception e){         e.printStackTrace();         }     }          public void initBean(){     for(BeanInformation beanInformation: beansInformation){     if(beanInformation.getName()!=null && !"".equals(beanInformation.getName())){     //通过反射机制,根据名字初始化这个类    try {singleton.put(beanInformation.getId(), Class.forName(beanInformation.getName()).newInstance());} catch (Exception e) {e.printStackTrace();}     }     }     }          /**  *    关于注入的实现  */ private void injectObject() { for(BeanInformation beanInformation : beansInformation){ Object bean = singleton.get(beanInformation.getId()); if(bean!=null){ try { PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for(PropertyInformation propertyInformation : beanInformation.getPropertyInformation()){ for(PropertyDescriptor properdesc : ps){ if(propertyInformation.getName().equals(properdesc.getName())){ Method setter = properdesc.getWriteMethod();//获取属性的setter方法 ,private if(setter!=null){ Object value = null; if(propertyInformation.getRef()!=null && !"".equals(propertyInformation.getRef().trim())){ value = singleton.get(propertyInformation.getRef()); }else{ value = ConvertUtils.convert(propertyInformation.getValue(), properdesc.getPropertyType()); } setter.setAccessible(true); setter.invoke(bean, value);//把引用对象注入到属性 } break; } } } } catch (Exception e) { } } } }      public Object getBean(String id){ return this.singleton.get(id);       }}

package junit.test;import java.util.HashSet;import java.util.Set;public class BeanInformation {    private String id;    private String name;    private Set<PropertyInformation> propertyInformation = new HashSet<PropertyInformation>();public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Set<PropertyInformation> getPropertyInformation() {return propertyInformation;}public void setPropertyInformation(Set<PropertyInformation> propertyInformation) {this.propertyInformation = propertyInformation;}}

package junit.test;public class PropertyInformation {    private String name;    private String ref;    private String value;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;}public String getValue() {return value;}public void setValue(String value) {this.value = value;}}

 

测试类:

package junit.test;import com.huxin.springinject.dao.Person;public class Test {public static void main(String[] args) {ApplicationContext ac = new ApplicationContext("applicationContext.xml");Person person = (Person)ac.getBean("chinese");person.save();person.useAxe();}}

 

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context"         xsi:schemaLocation="http://www.springframework.org/schema/beans           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd           http://www.springframework.org/schema/context            http://www.springframework.org/schema/context/spring-context-3.0.xsd">                   <bean id="chinese"  class="com.huxin.springinject.dao.impl.Chinese">         <property name="axe" ref="stoneAxe"/>      </bean>      <bean id="stoneAxe" class="com.huxin.springinject.dao.impl.StoneAxe"/></beans>

 

补充说明: 需要导入dom4j相应的辅助包和junit辅助包!