这里新增了对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>