美文网首页spring 相关
SpringIOC容器手写(二)--基于XML的容器

SpringIOC容器手写(二)--基于XML的容器

作者: aix91 | 来源:发表于2019-01-19 15:29 被阅读0次

    1. 解析XML文件拿到rootElement

        public List<Element> readXML() throws DocumentException {
            SAXReader reader = new SAXReader();
            Document document = reader.read(getResourceAsStream(xmlPath));
            Element rootElement = document.getRootElement();
            List<Element> elements = rootElement.elements();
            return elements;
        }
    

    2. 根据传入的beanId,在xml中找到相应的class name和属性名称和它的值

    • 找到beanId的Element
     private Element findElement(List<Element> elements, String beanId) {
            for (Element element : elements) {
                String xmlBeanId = element.attributeValue("id");
                if (StringUtils.isEmpty(xmlBeanId)) {
                    continue;
                }
                if (xmlBeanId.equals(beanId)) {
                    return element;
                }
            }
            return null;
        }
    
    • 找到beanId对应的className
        public String findClassPath(List<Element> elements, String beanId) throws Exception {
            Element element = findElement(elements, beanId);
            if (element == null) {
                throw new Exception("配置文件中没有该bean: " + beanId);
            } else return element.attributeValue("class");
        }
    
    • 找到beanId对应的属性值
     public Map<String, String> findProperties(List<Element> elements, String beanId) throws Exception {
            Map propertyMap = new HashMap();
    
            Element element = findElement(elements, beanId);
            if (element == null) {
                throw new Exception("配置文件中没有该bean: " + beanId);
            } else {
                List<Element> properties = element.elements("property");
                if (properties.isEmpty()) {
                } else {
                    properties.stream().forEach(property -> {
                        propertyMap.put(property.attributeValue("name"), property.attributeValue("value"));
                    });
                }
            }
            return propertyMap;
        }
    

    3. 利用反射,创建对象

    public Object newInstance(String className, Map<String, String> properties) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
            Class<?> classInfo = Class.forName(className);
            Object obj = classInfo.newInstance();
            if (properties.isEmpty()) {
            } else {
                properties.entrySet().stream().forEach(entry -> {
                    String key = entry.getKey();
                    String value = entry.getValue();
                    String setKey = "set" + key.toUpperCase().charAt(0) + key.substring(1);
                    try {
                        Method f = obj.getClass().getMethod(setKey, String.class);
                        f.setAccessible(true);
                        f.invoke(obj, value);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (NoSuchMethodException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                });
            }
    

    4. 定义getBean方法

     public Object getBean(String beanId) throws Exception {
            if (StringUtils.isEmpty(beanId)) {
                throw new Exception("beanId 不能为空");
            }
    
            List<Element> elements = readXML();
            if (elements == null || elements.isEmpty()) {
                throw new Exception("配置文件中没有配置bean信息");
            }
    
            String className = findClassPath(elements, beanId);
            Map propeties = findProperties(elements, beanId);
    
            return newInstance(className, propeties);
    
        }
    

    相关文章

      网友评论

        本文标题:SpringIOC容器手写(二)--基于XML的容器

        本文链接:https://www.haomeiwen.com/subject/imxzdqtx.html