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

spring自定义对ref属性支持

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

一、ThirdBean是一个测试的Bean类

  1. package com.spring1.bean;
  2.  
  3. public class ThirdBean {
  4. private SecondBean secondBean;
  5. private String username;
  6.  
  7. public SecondBean getSecondBean() {
  8. return secondBean;
  9. }
  10.  
  11. public void setSecondBean(SecondBean secondBean) {
  12. this.secondBean = secondBean;
  13. }
  14.  
  15. public String getUsername() {
  16. return username;
  17. }
  18.  
  19. public void setUsername(String username) {
  20. this.username = username;
  21. }
  22.  
  23. public void printUserInfo() {
  24. System.out.println(secondBean.getUserInfo() + ", " + username);
  25. }
  26. }

二、修改的xml解析类ParseXmlBean

  1. package com.spring1.parse;
  2.  
  3. import com.spring1.SpringUtil;
  4. import com.spring1.factory.BeanFactory;
  5. import org.dom4j.Document;
  6. import org.dom4j.Element;
  7. import org.dom4j.io.SAXReader;
  8.  
  9. import java.io.InputStream;
  10. import java.lang.reflect.Method;
  11. import java.util.HashMap;
  12. import java.util.List;
  13. import java.util.Map;
  14.  
  15. public class ParseXmlBean {
  16. static BeanFactory beanFactory = new BeanFactory();
  17. static Map<String, Element> elementMap = new HashMap<>();
  18.  
  19. public static BeanFactory parseXmlBean(String filepath) {
  20. SAXReader reader = new SAXReader();
  21. try {
  22. InputStream stream = ParseXmlBean.class.getClassLoader().getResourceAsStream(filepath);
  23. Document document = reader.read(stream);
  24. Element rootElement = document.getRootElement();
  25. List<Element> entries = rootElement.elements("bean");
  26. // 这个map记录id和元素,由于ref的原因
  27. for (Element entry : entries) {
  28. String beanId = entry.attributeValue("id");
  29. elementMap.put(beanId, entry);
  30. }
  31. for (Element entry : entries) {
  32. parseObjectElement(entry);
  33. }
  34. } catch (Exception e) {
  35. e.printStackTrace();
  36. }
  37. return beanFactory;
  38. }
  39.  
  40. private static String getMethodName(String name) {
  41. return "set" + SpringUtil.firstLetterUpper(name);
  42. }
  43.  
  44. /**
  45. * 对Bean的元素进行解析
  46. */
  47. public static Object parseObjectElement(Element entry) {
  48. String beanId = entry.attributeValue("id");
  49. // 如果已经解析了,那么就不需要再解析
  50. if (beanFactory.getBean(beanId) != null) {
  51. return beanFactory.getBean(beanId);
  52. }
  53. String beanClass = entry.attributeValue("class");
  54. Class<?> bean = null;
  55. try {
  56. bean = Class.forName(beanClass);
  57. Object beanObject = bean.newInstance();
  58. for (Object subEntry : entry.elements("property")) {
  59. String name = ((Element) subEntry).attributeValue("name");
  60. String value = ((Element) subEntry).attributeValue("value");
  61. String dataType = ((Element) subEntry).attributeValue("dataType");
  62. String ref = ((Element) subEntry).attributeValue("ref");
  63. if (ref != null) {
  64. Object object = beanFactory.getBean(ref); // 从工厂得到object
  65. // 如果object没有(有可能定义在后面),那么解析这个bean
  66. if (object == null) {
  67. Element element = elementMap.get(ref);
  68. Object refObject = parseObjectElement(element);
  69. Method method = bean.getMethod(getMethodName(refObject.getClass().getSimpleName()), new Class[]{refObject.getClass()});
  70. method.invoke(beanObject, new Object[]{refObject});
  71. } else {
  72. Method method = bean.getMethod(getMethodName(name), new Class[]{object.getClass()});
  73. method.invoke(beanObject, new Object[]{object});
  74. }
  75. beanFactory.setBean(beanId, beanObject);
  76. } else {
  77. Method method;
  78. if (dataType == null) {
  79. method = bean.getMethod(getMethodName(name), new Class[]{String.class});
  80. method.invoke(beanObject, new Object[]{value});
  81. } else if (dataType.equals("int")) {
  82. method = bean.getMethod(getMethodName(name), new Class[]{int.class});
  83. method.invoke(beanObject, new Object[]{Integer.valueOf(value)});
  84. }
  85. }
  86. }
  87. beanFactory.setBean(beanId, beanObject);
  88. return beanObject;
  89. } catch (Exception e) {
  90. e.printStackTrace();
  91. }
  92. return null;
  93. }
  94. }

三、测试的主体类

  1. package com.spring1.main;
  2.  
  3. import com.spring1.bean.FirstBean;
  4. import com.spring1.bean.SecondBean;
  5. import com.spring1.bean.ThirdBean;
  6. import com.spring1.factory.BeanFactory;
  7. import com.spring1.parse.ParseXmlBean;
  8. import org.junit.Test;
  9.  
  10. public class MainTest {
  11. @Test
  12. public void test_1() {
  13. BeanFactory beanFactory = ParseXmlBean.parseXmlBean("config/bean.xml");
  14. FirstBean firstBean = beanFactory.getBean("firstBean", FirstBean.class);
  15. String userInfo = firstBean.getUserInfo();
  16. System.out.println(userInfo);
  17.  
  18. SecondBean secondBean = (SecondBean) beanFactory.getBean("secondBean");
  19. String userInfo1 = secondBean.getUserInfo();
  20. System.out.println(userInfo1);
  21.  
  22. ThirdBean thirdBean = (ThirdBean) beanFactory.getBean("thirdBean");
  23. thirdBean.printUserInfo();
  24. }
  25. }

四、运行的结果如下

  1. huhx,
  2. liuling,
  3. liuling, , linux

五、定义的xml文件如下:

  1. <beans>
  2. <bean id="firstBean" class="com.spring1.bean.FirstBean">
  3. <property name="username" value="huhx"/>
  4. <property name="password" value="1234"/>
  5. </bean>
  6.  
  7. <bean id="thirdBean" class="com.spring1.bean.ThirdBean">
  8. <property name="secondBean" ref="secondBean"/>
  9. <property name="username" value="linux"/>
  10. </bean>
  11.  
  12. <bean id="secondBean" class="com.spring1.bean.SecondBean">
  13. <property name="age" value="21" dataType="int"/>
  14. <property name="name" value="liuling"/>
  15. </bean>
  16. </beans>

友情链接

spring基础---->spring自定义初始化(二)的更多相关文章

  1. spring基础---->spring自定义初始化(一)

    这里我们简单的实现一下spring中的初始化bean,以大概了解他的流程.受委屈几乎是一个人成长最快的途径,吃下去的是委屈,消化掉后得到的是格局. spring的自定义初始化 测试的项目结构如下: 一 ...

  2. spring基础---->spring自定义标签(一)

    Spring具有一个基于架构的扩展机制,可以使用xml文件定义和配置bean.本博客将介绍如何编写自定义XML bean的解析器,并用实例来加以说明.其实我一直相信 等你出现的时候我就知道是你. Sp ...

  3. spring基础学习01

    spring基础 Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用 IOC控制反转 把创建对象和维护对象之间的关系权利 ...

  4. Spring框架 - Spring和Spring框架组成

    Spring框架 - Spring和Spring框架组成 Spring是什么?它是怎么诞生的?有哪些主要的组件和核心功能呢? 本文通过这几个问题帮助你构筑Spring和Spring Framework ...

  5. [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.

    前言: 在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习 ...

  6. spring扩展点之二:spring中关于bean初始化、销毁等使用汇总,ApplicationContextAware将ApplicationContext注入

    <spring扩展点之二:spring中关于bean初始化.销毁等使用汇总,ApplicationContextAware将ApplicationContext注入> <spring ...

  7. 十二、Spring之IOC容器初始化

    Spring之IOC容器初始化 前言 在前面我们分析了最底层的IOC容器BeanFactory,接着简单分析了高级形态的容器ApplicationContext,在ApplicationContext ...

  8. Spring基础知识

    Spring基础知识 利用spring完成松耦合 接口 public interface IOutputGenerator { public void generateOutput(); } 实现类 ...

  9. Spring基础知识汇总 Java开发必看

    Spring简介 Spring框架由Rod Johnson开发,2004年发布了Spring框架的第一版.Spring是一个从实际开发中抽取出来的框架,因此它完成了大量开发中的通用步骤,留给开发者的仅 ...

随机推荐

  1. Lua------------------unity与lua的热更新

    [Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘终结篇:UniLua热更新完全解读 标签: 游戏开发游戏解决方案用户体验unity3d 2014-10-18 23:23 7680人阅读 ...

  2. Eclipse文件首部自动加 作者时间

    Window -> Preferences -> Java -> Code Style -> Code templates -> (in right-hand pane) ...

  3. linux环境下获取真实的ip地址

    package inas.test; import java.net.Inet6Address; import java.net.InetAddress; import java.net.Networ ...

  4. iOS: UIScrollView pauses NSTimer while scrolling

    StackOverflow http://stackoverflow.com/a/7059499 Question:I have a UIScrollView that has a series of ...

  5. 利用neon技术对矩阵旋转进行加速(2)

    上次介绍的是顺时针旋转90度,最近用到了180度和270度,在这里记录一下. 1.利用neon技术将矩阵顺时针旋转180度: 顺时针旋转180度比顺时针旋转90度容易很多,如下图 A1 A2 A3 A ...

  6. 【玩转Golang】 自定义json序列化对象时,非法字符错误原因

    由于前台web页面传来的日期对象是这样的格式“2010-11-03 15:23:22”,所以我安装网上查来的办法,自定义包装了time.Time对象,实现自己的Marshal和UnMarshal方法 ...

  7. RMAN:简单的duplicate创建新数据库 for 12c+

    构建参数文件 *.db_name='test2' ##### 需要注意的地方,和rman的duplicate目标库一致 *.compatible='18.0.0' ##### 关键的地方,每个版本的模 ...

  8. 用Python写简单的爬虫

    准备: 1.扒网页,根据URL来获取网页信息 import urllib.parse import urllib.request response = urllib.request.urlopen(& ...

  9. MysqlHelper使用反射机制智能推算数据类型以及属性名称

    public class MySqlHelper { private string ConnString; public MySqlHelper(string connectionString) { ...

  10. phpcms v9不限模型全站搜索

    简单修改一下v9默认的搜索功能,可以不按模型搜索全站内容 下面是被修改后的search模块中的index.php文件 <?php defined('IN_PHPCMS') or exit('No ...