模拟实现spring框架中的实例化对象和注入

时间:2021-04-12 09:22:53

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;
    }

}




相关文章