spring基础---->spring自定义初始化(二)

  这里新增了对ref属性的支持,并且过滤了已经解析的元素。人生有两个词很棒,一言不合和不提也罢。

spring自定义对ref属性支持

 项目的结构如下:新增一个ThirdBean类,修改了ParseXmlBean和MainTest两个类。

一、ThirdBean是一个测试的Bean类

package com.spring1.bean;

public class ThirdBean {
    private SecondBean secondBean;
    private String username;

    public SecondBean getSecondBean() {
        return secondBean;
    }

    public void setSecondBean(SecondBean secondBean) {
        this.secondBean = secondBean;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void printUserInfo() {
        System.out.println(secondBean.getUserInfo() + ", " + username);
    }
}

二、修改的xml解析类ParseXmlBean

package com.spring1.parse;

import com.spring1.SpringUtil;
import com.spring1.factory.BeanFactory;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ParseXmlBean {
    static BeanFactory beanFactory = new BeanFactory();
    static Map<String, Element> elementMap = new HashMap<>();

    public static BeanFactory parseXmlBean(String filepath) {
        SAXReader reader = new SAXReader();
        try {
            InputStream stream = ParseXmlBean.class.getClassLoader().getResourceAsStream(filepath);
            Document document = reader.read(stream);
            Element rootElement = document.getRootElement();
            List<Element> entries = rootElement.elements("bean");
            // 这个map记录id和元素,由于ref的原因
            for (Element entry : entries) {
                String beanId = entry.attributeValue("id");
                elementMap.put(beanId, entry);
            }
            for (Element entry : entries) {
                parseObjectElement(entry);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return beanFactory;
    }

    private static String getMethodName(String name) {
        return "set" + SpringUtil.firstLetterUpper(name);
    }

    /**
     * 对Bean的元素进行解析
     */
    public static Object parseObjectElement(Element entry) {
        String beanId = entry.attributeValue("id");
        // 如果已经解析了,那么就不需要再解析
        if (beanFactory.getBean(beanId) != null) {
            return beanFactory.getBean(beanId);
        }
        String beanClass = entry.attributeValue("class");
        Class<?> bean = null;
        try {
            bean = Class.forName(beanClass);
            Object beanObject = bean.newInstance();
            for (Object subEntry : entry.elements("property")) {
                String name = ((Element) subEntry).attributeValue("name");
                String value = ((Element) subEntry).attributeValue("value");
                String dataType = ((Element) subEntry).attributeValue("dataType");
                String ref = ((Element) subEntry).attributeValue("ref");
                if (ref != null) {
                    Object object = beanFactory.getBean(ref); // 从工厂得到object
                    // 如果object没有(有可能定义在后面),那么解析这个bean
                    if (object == null) {
                        Element element = elementMap.get(ref);
                        Object refObject = parseObjectElement(element);
                        Method method = bean.getMethod(getMethodName(refObject.getClass().getSimpleName()), new Class[]{refObject.getClass()});
                        method.invoke(beanObject, new Object[]{refObject});
                    } else {
                        Method method = bean.getMethod(getMethodName(name), new Class[]{object.getClass()});
                        method.invoke(beanObject, new Object[]{object});
                    }
                    beanFactory.setBean(beanId, beanObject);
                } else {
                    Method method;
                    if (dataType == null) {
                        method = bean.getMethod(getMethodName(name), new Class[]{String.class});
                        method.invoke(beanObject, new Object[]{value});
                    } else if (dataType.equals("int")) {
                        method = bean.getMethod(getMethodName(name), new Class[]{int.class});
                        method.invoke(beanObject, new Object[]{Integer.valueOf(value)});
                    }
                }
            }
            beanFactory.setBean(beanId, beanObject);
            return beanObject;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

 三、测试的主体类

package com.spring1.main;

import com.spring1.bean.FirstBean;
import com.spring1.bean.SecondBean;
import com.spring1.bean.ThirdBean;
import com.spring1.factory.BeanFactory;
import com.spring1.parse.ParseXmlBean;
import org.junit.Test;

public class MainTest {
    @Test
    public void test_1() {
        BeanFactory beanFactory = ParseXmlBean.parseXmlBean("config/bean.xml");
        FirstBean firstBean = beanFactory.getBean("firstBean", FirstBean.class);
        String userInfo = firstBean.getUserInfo();
        System.out.println(userInfo);

        SecondBean secondBean = (SecondBean) beanFactory.getBean("secondBean");
        String userInfo1 = secondBean.getUserInfo();
        System.out.println(userInfo1);

        ThirdBean thirdBean = (ThirdBean) beanFactory.getBean("thirdBean");
        thirdBean.printUserInfo();
    }
}

四、运行的结果如下

huhx, 1234
liuling, 21
liuling, 21, linux

五、定义的xml文件如下:

<beans>
    <bean id="firstBean" class="com.spring1.bean.FirstBean">
        <property name="username" value="huhx"/>
        <property name="password" value="1234"/>
    </bean>

    <bean id="thirdBean" class="com.spring1.bean.ThirdBean">
        <property name="secondBean" ref="secondBean"/>
        <property name="username" value="linux"/>
    </bean>

    <bean id="secondBean" class="com.spring1.bean.SecondBean">
        <property name="age" value="21" dataType="int"/>
        <property name="name" value="liuling"/>
    </bean>
</beans>

友情链接

原文地址:https://www.cnblogs.com/huhx/p/baseusemyspring2.html