编写一个实现 IOC 功能的简单 Spring 框架,包含对象注册、对象管理、及暴 露给外部获取对象的功能,并编写测试程序。扩展注册器的方式,要求采用 XML 和 txt 文件。

源代码

package myspring;import java.lang.reflect.Method;
import java.util.Map;/*** 最顶层的IOC实现* 该类负责从注册器中取出注册对象* 实现从对象描述信息转换为对象实例的过程、* 实现根据名称获取对象的方法*/
public abstract class AbstractBeanFactory implements BeanFactory {private String filePath;   //注册文件路径private Map<String,BeanInfo> container; //注册对象信息Mapprotected SourceReader reader; //对象注册读取器public AbstractBeanFactory(String filePath){this.filePath = filePath;}/*** 该方法为抽象方法,需有子类类实现,用于指定使用什么样的注册读取器* @param reader 指定的注册读取器*/protected abstract void setSourceReader(SourceReader reader);// 从注册读取器中读取,注册对象的信息MAPpublic void registerBeans(){this.container = this.reader.loadBeans(filePath);}//  实现BeanFactory定义的根据名称获取指定对象的方法@Overridepublic Object getBean(String name) {BeanInfo beaninfo = this.container.get(name); //根据对象名获取该对象的描述信息if(beaninfo == null){ //如果容器中不存在该对象的描述信息,则返回null,此处可以抛开一个异常return null;}else{ //根据对象信息,解析并生成指定对象实例,返回给用户return this.parseBean(beaninfo);}}  /*** 解析并生成对象实例* 该方法主要通过反射完成,步骤如下:* 1.根据类名,加载指定类,并获取该类的貌似Class对象clazz* 2.使用Class对象clazz实例化该类,获取一个对象,注意,这儿实例化对象时,采用的无参构造方法,因此要求注册的对象必须含有无参构造方法* 3.逐个设置对象字段的值,这儿采用setter Method方式,而不是直接使用Field对象的原因是,用户有可能在setter对象中,对注入的值进行额外处理,如格式化等* 4.返回对象实例* @param beaninfo 指定对象的描述信息* @return*/protected Object parseBean(BeanInfo beaninfo){Class clazz; try {clazz = Class.forName(beaninfo.getType()); //根据对象的全类名,指定类Object bean = clazz.newInstance(); //使用注册对象的无参构造函数,实例化对象实例Method[] methods = clazz.getMethods(); //获取该类声明的所有公共方法,其实Spring获取的是所有方法,包括非公有的for(String property : beaninfo.getProperties().keySet()){ //遍历对象的所有属性,进行赋值String setter = "set" + StringUtil.firstCharToUp(property); //获取属性的setter方法名称for(Method method : methods){ //遍历该类的所有公有方法String methodName = method.getName(); //获取方法名称if(methodName.equals(setter)){ //比较方法名与属性的setter方法名是否相同,如果相同则进行赋值Object value = beaninfo.getProperties().get(property); //从对象描述信息中获取该属性的值method.invoke(bean,value); //通过反射对属性进行赋值continue; //对下一属性赋值}}}return bean; //返回指定的对象} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} return null;}}package myspring;/*** IOC容器的顶层接口*/
public interface BeanFactory {/*** 根据对象的名称标识来获取对象实例* @param name 对象名称,即对象描述信息中的对象标识* @return 指定名称的对象实例*/Object getBean(String name);
}package myspring;import java.util.HashMap;
import java.util.Map;//该类用于描述注册在容器中的对象
public class BeanInfo {private String id; //对象的标识private String type; //对象的类型,即全类名private Map<String,Object> properties = new HashMap<String,Object>(); //对象的属性及值得集合 public String getId() {return id;}public void setId(String id) {this.id = id;}public String getType() {return type;}public void setType(String type) {this.type = type;}public Map<String,Object> getProperties() {return properties;}public void setProperties(Map<String, Object> properties) {this.properties = properties;}public void addProperty(String name, Object value){this.properties.put(name, value);}
}
package myspring;public class Bootstrap {public static void main(String[] args) {BeanFactory factory = new TXTContext("bean.txt");Speakable s = (Speakable)factory.getBean("Person");s.speak("Lesson one!");}
}
package myspring;public class Person implements Speakable {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic void speak(String message) {System.out.println( this.name + " say: " + message);}
}
package myspring;import java.util.Map;/*** 注册读取器接口* 负责从读取用户注册的对象* 继承该接口的类可以实现多种读取方式,如从配置文件中读取,根据标注读取,从网络中读取等*/
public interface SourceReader {/*** 读取用户注册的对象信息* @param filePath 读取录取* @return 注册对象信息Map*/Map<String,BeanInfo> loadBeans(String filePath);
}
package myspring;public interface Speakable {public void speak(String message);
}
package myspring;public class StringUtil {/*public static void main(String[] args) {System.out.println(StringUtil.firstCharToUp(str)); }*/public static String firstCharToUp(String str){char ch[]=str.toCharArray();char ch1=Character.toUpperCase(ch[0]);ch[0]=ch1;String s=new String(ch);return s;}public static String firstCharToLower(String str){char ch[]=str.toCharArray();char ch1=Character.toLowerCase(ch[0]);ch[0]=ch1;String s=new String(ch);return s;}
}
package myspring;public class TXTContext extends AbstractBeanFactory {/*** 上下文的构造方法* 该方法中指明注册读取器* 并在构造该方法时一次性的加载注册的对象* @param filePath*/public TXTContext(String filePath) {super(filePath);this.setSourceReader(new TXTSourceReader()); //添加注册读取器,此处的注册读取器为XMLSourceReaderthis.registerBeans(); //加载注册的对象信息}//  设置注册读取器@Overrideprotected void setSourceReader(SourceReader reader) {this.reader = reader;}
}package myspring;import org.w3c.dom.*;
import org.xml.sax.SAXException;import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.util.HashMap;
import java.util.Map;public class TXTSourceReader implements SourceReader{/*** 实现读取注册对象信息方法* 此处只是模拟测试使用,感兴趣的同学可以自己书写通过配置文件读取的实现*/@Overridepublic Map<String, BeanInfo> loadBeans(String filePath) {//初始化一个对象信息Map<String,BeanInfo> beans = new HashMap<String,BeanInfo>(); //初始化一个对象信息MapBeanInfo beanInfo=new BeanInfo();File filename = new File("bean.txt"); // 要读取以上路径的input。txt文件InputStreamReader reader = null; // 建立一个输入流对象readertry {reader = new InputStreamReader(new FileInputStream(filename));BufferedReader br = new BufferedReader(reader); // 建立一个对象,它把文件内容转成计算机能读懂的语言String line = "";line = br.readLine();while (line != null) {String[] t=line.split("=");System.out.println(t[0]+t[1]);if(t[0].equals("id")){beanInfo.setId(t[1]);}else if(t[0].equals("class")){beanInfo.setType(t[1]);}else beanInfo.addProperty(t[0],t[1]);line = br.readLine();}} catch (FileNotFoundException fileNotFoundException) {fileNotFoundException.printStackTrace();} catch (IOException ioException){ioException.printStackTrace();}beans.put(beanInfo.getId(),beanInfo);return beans; //返回对象信息MAP}package myspring;public class XMLContext extends AbstractBeanFactory{/*** 上下文的构造方法* 该方法中指明注册读取器* 并在构造该方法时一次性的加载注册的对象* @param filePath*/public XMLContext(String filePath) {super(filePath);this.setSourceReader(new XMLSourceReader()); //添加注册读取器,此处的注册读取器为XMLSourceReaderthis.registerBeans(); //加载注册的对象信息}  //  设置注册读取器@Overrideprotected void setSourceReader(SourceReader reader) {this.reader = reader;}
}package myspring;import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.xpath.XPath;import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;/*** XML注册读取器* 该类继承了注册读取器接口,并模拟实现了读取注册对象信息的方法*/
public class XMLSourceReader implements SourceReader {/*** 实现读取注册对象信息方法* 此处只是模拟测试使用,感兴趣的同学可以自己书写通过配置文件读取的实现*/@Overridepublic Map<String, BeanInfo> loadBeans(String filePath) {//初始化一个对象信息Map<String,BeanInfo> res = new HashMap<String,BeanInfo>(); //初始化一个对象信息Maptry {SAXBuilder builder = new SAXBuilder();Document doc = null;doc = (Document) builder.build(new File("book.xml"));  XPath xpath = null;    xpath = XPath.newInstance("//bean");List beans = null;beans = xpath.selectNodes(doc);  Iterator i = beans.iterator();while (i.hasNext()) {BeanInfo beaninfo = new BeanInfo();Element bean = (Element) i.next();String id = bean.getAttributeValue("id");String cls = bean.getAttributeValue("class");beaninfo.setId(id);beaninfo.setType(cls);List<Element> list = bean.getChildren("property");for (Element el : list) {if (el.getAttribute("name") != null) {beaninfo.addProperty(el.getAttributeValue("name"),el.getAttributeValue("value"));}}res.put(beaninfo.getId(),beaninfo);}} catch (JDOMException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return res;}
}}

Java—实现 IOC 功能的简单 Spring 框架相关推荐

  1. java邮件模板代码_Java的Spring框架中实现发送邮件功能的核心代码示例

    Spring中已经封装了邮件操作类,通过spring配置文件可以便捷地注入到controller.action等地方. 下面是配置: p:host="${mail.host}" p ...

  2. java jdbc jar包_通过 Spring 框架如何进行JDBC操作呢?

    Spring 整合 JDBC 的方式 添加依赖 编写配置文件 db.properties bean.xml 配置修改 配置数据源 模板类配置 测试整合结果 案例实操 添加依赖 数据库驱动 jar 包 ...

  3. java 实现ps功能_java 简单图片,可以实现ps的几个小滤镜

    java 简单图片,可以实现ps的几个小滤镜 以下教你实现图片马赛克,黑白画,珠纹化,油画效果等处理技术原理及实现.看完自己也可以简单的玩一玩. 1. 需要用到的包 java.awt // 用于创建用 ...

  4. java配置文件报错_java使用spring框架配置文件时遇到的错误——Referenced file contains errors...

    报错信息: Referenced file contains errors (http://www.springframework.org/schema/beans/spring-beans-4.3. ...

  5. Java运用注解反射编写简单测试框架

    测试一个计算器类,把异常类型次数其他异常信息自动生成BUG文件 /*** 计算器类*/ public class Calculator {//加法@Checkpublic void add(){Sys ...

  6. 基于java spring框架开发部标1078视频监控平台精华文章索引

    部标1078视频监控平台,是一个庞杂的工程,涵盖了多层协议,部标jt808,jt809,jt1078,苏标Adas协议等,多个平台功能标准,部标796标准,部标1077标准和苏标主动安全标准,视频方面 ...

  7. Spring框架——IOC、DI

    本篇博客主要介绍Java中的IOC和DI,以及在String框架中的应用.首先,我们将对IOC和DI进行概念介绍,然后讲解它们的关系及在String框架中的应用,最后通过一个实例来展示它们的具体用法. ...

  8. Eclipse搭建简单的Spring框架

    今天在这儿记录一下如何搭建一个简单Spring框架 一.首先需要新建一个工程(我新建的是web工程): file-->new-->other-->dynamic ** **,如图: ...

  9. effective java英文版pdf_Java之Spring1:Spring简介、环境搭建、源码下载及导入MyEclipse...

    框架学习前言 这个模块是面向Spring的,Spring的学习我是这么想的: 1.简单介绍Spring,主要是从网上借鉴一些重点 2.尽量说明清楚Spring的使用方法以及细节点 3.尽量以自己的理解 ...

最新文章

  1. Non-Maximum Suppression,NMS非极大值抑制
  2. 每天五分钟linux(8)-cp
  3. java数组1 100偶数和_java – 数组偶数和奇数排序
  4. java 中的对象序列化
  5. android 蒙版图片带拖动_Android实现蒙版弹出框效果
  6. POJ 2287 - Tian Ji -- The Horse Racing(贪心)
  7. 壁仞科技A轮融资11亿元, 创近年芯片设计领域新纪录
  8. Linux环境安装配置JDK
  9. COJ 1079 树上的查询 (离线LCA)
  10. 夜神模拟器安装drozer
  11. eight后缀勒索病毒百胜系统数据库成功恢复
  12. mac android usb共享网络,mac 网络共享软件 手机usb共享网络方法和技巧详解介绍
  13. IEEE TGRS2019|【论文笔记】R2-CNN: Fast Tiny Object Detection in Large-Scale Remote Sensing Images
  14. python str和repr的区别_python的str()和repr()的区别
  15. 今日头条前端实习面试经验
  16. Java将下划线大写方式命名的字符串转换为驼峰式
  17. 服务降级是什么?Spring Cloud如何实现?
  18. 概率论数理统计 挺全的
  19. 电容柜是干什么用的?加装电容柜起什么作用?电容柜的用途
  20. 泰拉瑞亚安装、运行教程

热门文章

  1. Unix 网络编程(四)- 典型TCP客服服务器程序开发实例及基本套接字API介绍
  2. Java面试题中高级,javaif循环语句
  3. PHPCMS的产品筛选功能
  4. 使用Nginx+uWSGI部署Django项目
  5. 05精益敏捷项目管理——超越Scrum
  6. 2018.10.24 NOIP模拟 小 C 的序列(链表+数论)
  7. mac 下终端 操作svn命令 以及出现证书错误的处理方法
  8. 调用方法mssql_fetch_row、mssql_fetch_array、mssql_fetch_assoc和mssql_fetch_objcect读取数据的区别...
  9. 完整的Android 新浪微博api调用DEMO
  10. (教学思路 C#之类五)类的分类(静态类、实例类、嵌套类、结构、简单的抽象类、简单的密封类)...