Java代码实现依赖注入
2016-05-25 07:40
615 查看
(转载)http://zhangjunhd.blog.51cto.com/113473/126545
这里将模仿Spring实现一种基于xml配置文件的依赖注入机制。文件中将实现3中注入,一是单值注入,包括int,float,double,char等,也包括String注入;二是Java容器注入,包括List,Set,Map三种容器的注入,最后一种是java
bean对象注入。
实现的机制是,使用Dom4j对xml配置文件进行解析,这里使用dom4j的Element Handler机制,一种类似与责任链模式的实现机制;对于java对象的构建使用反射机制,这里主要是针对得到的类的Field进行set赋值。我试图通过调用Method的invoke方法调用类本身的setter方法,但是由于通过xml解析得到的值都是String,如果将这些String动态的转换为相应的确定类型是个难点,Method的invoke方法,如果形参是int,而传入java.lang.Integer,它不会认,所以尝试失败,只能通过Field的set方法传入特定值。
配置文件setting.xml
依据setting.xml,这里将构建两个Person类的实例me和you:
Person.java
紧接着,构建一个ListOne的实例myList:
ListOne.java
紧接着,构建一个SetOne的实例mySet:
SetOne.java
紧接着,构建一个MapOne的实例myMap:
MapOne.java
最后构建一个Persons类的实例us,其中包含me和you两个已经构建好的对象:
Persons.java
主要的实现机制是(代码BeanFactory.java以及工程见附件),
1.通过一个HashMap保存构造好的对象,key就是bean的id属性,value就是这个对象;
查询时
2.init方法读入配置文件setting.xml,并直接定位到beans下的bean元素,并实例化一个ElementHandler对其处理。
3.ElementHandler,dom4j的ElementHandler接口有两个方法,一个是onStart(),它主要用于处理该元素的属性以及动态增加新的Handler类;另一个是onEnd(),它主要用于获得该元素的Text文本以及删除已添加的Handler。
BeanHandler
PropertyHandler
根据setting.xml,我们可以得到各种注入元素的Handler类处理流程图。
![](http://zhangjunhd.blog.51cto.com/attachment/200901/200901151231978434633.jpg)
4. setFieldValue()基于反射机制和相应的类信息得到Field的类型,并根据setting.xml设置它的值。
5.测试
测试结果:
[align=left]ZJ 26 1.78[/align]
[align=left]Mary 27 1.66[/align]
[align=left][java, c, windows][/align]
[align=left][cat, tom, dog][/align]
[align=left]{c=CHINA, j=JAPAN, k=KOREA}[/align]
[align=left]com.zj.ioc.di.imp.Person@1a5ab41[/align]
com.zj.ioc.di.imp.Person@18e3e60
本文出自 “子 孑” 博客,请务必保留此出处http://zhangjunhd.blog.51cto.com/113473/126545
这里将模仿Spring实现一种基于xml配置文件的依赖注入机制。文件中将实现3中注入,一是单值注入,包括int,float,double,char等,也包括String注入;二是Java容器注入,包括List,Set,Map三种容器的注入,最后一种是java
bean对象注入。
实现的机制是,使用Dom4j对xml配置文件进行解析,这里使用dom4j的Element Handler机制,一种类似与责任链模式的实现机制;对于java对象的构建使用反射机制,这里主要是针对得到的类的Field进行set赋值。我试图通过调用Method的invoke方法调用类本身的setter方法,但是由于通过xml解析得到的值都是String,如果将这些String动态的转换为相应的确定类型是个难点,Method的invoke方法,如果形参是int,而传入java.lang.Integer,它不会认,所以尝试失败,只能通过Field的set方法传入特定值。
配置文件setting.xml
[align=left]<?xml version="1.0" encoding="UTF-8"?>[/align] [align=left] [/align] [align=left]<beans>[/align] [align=left] <bean id="me" class="com.zj.ioc.di.imp.Person">[/align] [align=left] <property name="name">[/align] [align=left] <value>ZJ</value>[/align] [align=left] </property>[/align] [align=left] <property name="age">[/align] [align=left] <value>26</value>[/align] [align=left] </property>[/align] [align=left] <property name="height">[/align] [align=left] <value>1.78</value>[/align] [align=left] </property>[/align] [align=left] </bean>[/align] [align=left] <bean id="you" class="com.zj.ioc.di.imp.Person">[/align] [align=left] <property name="name">[/align] [align=left] <value>Mary</value>[/align] [align=left] </property>[/align] [align=left] <property name="age">[/align] [align=left] <value>27</value>[/align] [align=left] </property>[/align] [align=left] <property name="height">[/align] [align=left] <value>1.66</value>[/align] [align=left] </property>[/align] [align=left] </bean>[/align] [align=left] <bean id="myList" class="com.zj.ioc.di.imp.ListOne">[/align] [align=left] <property name="msg">[/align] [align=left] <list>[/align] [align=left] <value>java</value>[/align] [align=left] <value>c</value>[/align] [align=left] <value>windows</value>[/align] [align=left] </list>[/align] [align=left] </property>[/align] [align=left] </bean>[/align] [align=left] <bean id="mySet" class="com.zj.ioc.di.imp.SetOne">[/align] [align=left] <property name="msg">[/align] [align=left] <set>[/align] [align=left] <value>tom</value>[/align] [align=left] <value>cat</value>[/align] [align=left] <value>dog</value>[/align] [align=left] </set>[/align] [align=left] </property>[/align] [align=left] </bean>[/align] [align=left] <bean id="myMap" class="com.zj.ioc.di.imp.MapOne">[/align] [align=left] <property name="msg">[/align] [align=left] <map>[/align] [align=left] <entry key="c">[/align] [align=left] <value>CHINA</value>[/align] [align=left] </entry>[/align] [align=left] <entry key="j">[/align] [align=left] <value>JAPAN</value>[/align] [align=left] </entry>[/align] [align=left] <entry key="k">[/align] [align=left] <value>KOREA</value>[/align] [align=left] </entry>[/align] [align=left] </map>[/align] [align=left] </property>[/align] [align=left] </bean>[/align] [align=left] <bean id="us" class="com.zj.ioc.di.imp.Persons">[/align] [align=left] <property name="i">[/align] [align=left] <ref bean="me" />[/align] [align=left] </property>[/align] [align=left] <property name="u">[/align] [align=left] <ref bean="you" />[/align] [align=left] </property>[/align] [align=left] </bean>[/align] </beans> |
依据setting.xml,这里将构建两个Person类的实例me和you:
Person.java
[align=left]package com.zj.ioc.di.imp;[/align] [align=left] [/align] [align=left]public class Person {[/align] [align=left] private String name;[/align] [align=left] private int age;[/align] [align=left] private float height;[/align] [align=left] [/align] [align=left] public String getName() {return name;}[/align] public void setName(String name) {this.name = name;} [align=left] public int getAge() {return age;}[/align] public void setAge(int age) {this.age = age;} [align=left] public float getHeight() {return height;}[/align] public void setHeight(float height) {this.height = height;} [align=left]}[/align] |
ListOne.java
[align=left]package com.zj.ioc.di.imp;[/align] [align=left]import java.util.List;[/align] [align=left] [/align] [align=left]public class ListOne {[/align] [align=left] private List<String> msg;[/align] [align=left] [/align] [align=left] public List<String> getMsg() {return msg;}[/align] public void setMsg(List<String> msg) {this.msg = msg;} [align=left]}[/align] |
SetOne.java
[align=left]package com.zj.ioc.di.imp;[/align] [align=left]import java.util.Set;[/align] [align=left] [/align] [align=left]public class SetOne {[/align] [align=left] private Set<String> msg;[/align] [align=left] [/align] [align=left] public Set<String> getMsg() {return msg;}[/align] public void setMsg(Set<String> msg) {this.msg = msg;} } |
MapOne.java
[align=left]package com.zj.ioc.di.imp;[/align] [align=left]import java.util.Map;[/align] [align=left] [/align] [align=left]public class MapOne {[/align] [align=left] private Map<String,String> msg;[/align] [align=left] [/align] [align=left] public Map<String, String> getMsg() {return msg;}[/align] public void setMsg(Map<String, String> msg) {this.msg = msg;} } |
Persons.java
[align=left]package com.zj.ioc.di.imp;[/align] [align=left] [/align] [align=left]public class Persons {[/align] [align=left] private Person i;[/align] [align=left] private Person u;[/align] [align=left] [/align] [align=left] public Person getI() {return i;}[/align] public void setI(Person i) {this.i = i;} [align=left] public Person getU() {return u;}[/align] public void setU(Person u) {this.u = u;} [align=left]}[/align] |
主要的实现机制是(代码BeanFactory.java以及工程见附件),
1.通过一个HashMap保存构造好的对象,key就是bean的id属性,value就是这个对象;
private Map<String, Object> beanMap = new HashMap<String, Object>(); …… [align=left]public Object getBean(String beanId) {[/align] [align=left] Object obj = beanMap.get(beanId);[/align] [align=left] return obj;[/align] } |
[align=left]BeanFactory factory = new BeanFactory();[/align] [align=left]factory.init("setting.xml");[/align] Person p1 = (Person) factory.getBean("me"); |
2.init方法读入配置文件setting.xml,并直接定位到beans下的bean元素,并实例化一个ElementHandler对其处理。
public void init(String xmlUri) throws Exception { [align=left] SAXReader saxReader = new SAXReader();[/align] [align=left] File file = new File(xmlUri);[/align] [align=left] try {[/align] [align=left] saxReader.addHandler("/beans/bean", new BeanHandler());[/align] [align=left] saxReader.read(file);[/align] [align=left] } catch (DocumentException e) {[/align] [align=left] System.out.println(e.getMessage());[/align] [align=left] }[/align] } |
3.ElementHandler,dom4j的ElementHandler接口有两个方法,一个是onStart(),它主要用于处理该元素的属性以及动态增加新的Handler类;另一个是onEnd(),它主要用于获得该元素的Text文本以及删除已添加的Handler。
BeanHandler
private class BeanHandler implements ElementHandler { [align=left] Object obj = null;[/align] [align=left] [/align] public void .Start(ElementPath path) { [align=left] Element beanElement = path.getCurrent();[/align] [align=left] Attribute classAttribute = beanElement.attribute("class");[/align] [align=left] [/align] [align=left] Class<?> bean = null;[/align] [align=left] try {[/align] [align=left] bean = Class.forName(classAttribute.getText());[/align] [align=left] } catch (ClassNotFoundException e) {[/align] [align=left] e.printStackTrace();[/align] [align=left] }[/align] [align=left] Field fields[] = bean.getDeclaredFields();[/align] [align=left] Map<String, Field> mapField = new HashMap<String, Field>();[/align] [align=left] for (Field field : fields)[/align] [align=left] mapField.put(field.getName(), field);[/align] [align=left] try {[/align] [align=left] obj = bean.newInstance();[/align] [align=left] } catch (InstantiationException e) {[/align] [align=left] e.printStackTrace();[/align] [align=left] } catch (IllegalAccessException e) {[/align] [align=left] e.printStackTrace();[/align] [align=left] }[/align] [align=left] [/align] [align=left] path.addHandler("property", new PropertyHandler(mapField, obj));[/align] [align=left] }[/align] [align=left] [/align] public void .End(ElementPath path) { [align=left] Element beanElement = path.getCurrent();[/align] [align=left] Attribute idAttribute = beanElement.attribute("id");[/align] [align=left] beanMap.put(idAttribute.getText(), obj);[/align] [align=left] path.removeHandler("property");[/align] [align=left] }[/align] } |
PropertyHandler
private class PropertyHandler implements ElementHandler { [align=left] Map<String, Field> mapField;[/align] [align=left] Object obj;[/align] [align=left] [/align] [align=left] public PropertyHandler(Map<String, Field> mapField, Object obj) {[/align] [align=left] this.mapField = mapField;[/align] [align=left] this.obj = obj;[/align] [align=left] }[/align] [align=left] [/align] public void .Start(ElementPath path) { [align=left] Element propertyElement = path.getCurrent();[/align] [align=left] Attribute nameAttribute = propertyElement.attribute("name");[/align] [align=left] path.addHandler("value", new ValueHandler(mapField, obj,[/align] [align=left] nameAttribute));[/align] [align=left] path.addHandler("list", new ListHandler(mapField, obj,[/align] [align=left] nameAttribute));[/align] [align=left] path.addHandler("set", new SetHandler(mapField, obj,[/align] [align=left] nameAttribute));[/align] [align=left] path.addHandler("map", new MapHandler(mapField, obj,[/align] [align=left] nameAttribute));[/align] [align=left] path.addHandler("ref", new RefHandler(mapField, obj,[/align] [align=left] nameAttribute));[/align] [align=left] }[/align] [align=left] [/align] public void .End(ElementPath path) { [align=left] path.removeHandler("value");[/align] [align=left] path.removeHandler("list");[/align] [align=left] path.removeHandler("set");[/align] [align=left] path.removeHandler("map");[/align] [align=left] path.removeHandler("ref");[/align] [align=left] }[/align] } |
根据setting.xml,我们可以得到各种注入元素的Handler类处理流程图。
![](http://zhangjunhd.blog.51cto.com/attachment/200901/200901151231978434633.jpg)
4. setFieldValue()基于反射机制和相应的类信息得到Field的类型,并根据setting.xml设置它的值。
private void setFieldValue(Object obj, Field field, String value) { [align=left] String fieldType = field.getType().getSimpleName();[/align] [align=left] try {[/align] [align=left] if (fieldType.equals("int"))[/align] [align=left] field.setInt(obj, new Integer(value));[/align] [align=left] else if (fieldType.equals("float"))[/align] [align=left] field.setFloat(obj, new Float(value));[/align] [align=left] else if (fieldType.equals("boolean"))[/align] [align=left] field.setBoolean(obj, new Boolean(value));[/align] [align=left] else if (fieldType.equals("char"))[/align] [align=left] field.setChar(obj, value.charAt(0));[/align] [align=left] else if (fieldType.equals("double"))[/align] [align=left] field.setDouble(obj, new Double(value));[/align] [align=left] else if (fieldType.equals("long"))[/align] [align=left] field.setLong(obj, new Long(value));[/align] [align=left] else[/align] [align=left] field.set(obj, value);[/align] [align=left] } catch (IllegalArgumentException e) {[/align] [align=left] e.printStackTrace();[/align] [align=left] } catch (IllegalAccessException e) {[/align] [align=left] e.printStackTrace();[/align] [align=left] }[/align] [align=left]}[/align] [align=left] [/align] private void setFieldValue(Object obj, Field field, List<String> value) { [align=left] try {[/align] [align=left] field.set(obj, value);[/align] [align=left] } catch (IllegalArgumentException e) {[/align] [align=left] e.printStackTrace();[/align] [align=left] } catch (IllegalAccessException e) {[/align] [align=left] e.printStackTrace();[/align] [align=left] }[/align] } |
5.测试
public static void main(String[] args) { [align=left] try {[/align] [align=left] BeanFactory factory = new BeanFactory();[/align] [align=left] factory.init("setting.xml");[/align] [align=left] [/align] [align=left] Person p1 = (Person) factory.getBean("me");[/align] [align=left] System.out.print(p1.getName() + " ");[/align] [align=left] System.out.print(p1.getAge() + " ");[/align] [align=left] System.out.println(p1.getHeight());[/align] [align=left] [/align] [align=left] Person p2 = (Person) factory.getBean("you");[/align] [align=left] System.out.print(p2.getName() + " ");[/align] [align=left] System.out.print(p2.getAge() + " ");[/align] [align=left] System.out.println(p2.getHeight());[/align] [align=left] [/align] [align=left] ListOne list = (ListOne) factory.getBean("myList");[/align] [align=left] System.out.println(list.getMsg());[/align] [align=left] [/align] [align=left] SetOne set = (SetOne) factory.getBean("mySet");[/align] [align=left] System.out.println(set.getMsg());[/align] [align=left] [/align] [align=left] MapOne map = (MapOne) factory.getBean("myMap");[/align] [align=left] System.out.println(map.getMsg());[/align] [align=left] [/align] [align=left] Persons us = (Persons) factory.getBean("us");[/align] [align=left] System.out.println(us.getI());[/align] [align=left] System.out.println(us.getU());[/align] [align=left] } catch (Exception e) {[/align] [align=left] e.printStackTrace();[/align] [align=left] }[/align] } |
[align=left]ZJ 26 1.78[/align]
[align=left]Mary 27 1.66[/align]
[align=left][java, c, windows][/align]
[align=left][cat, tom, dog][/align]
[align=left]{c=CHINA, j=JAPAN, k=KOREA}[/align]
[align=left]com.zj.ioc.di.imp.Person@1a5ab41[/align]
com.zj.ioc.di.imp.Person@18e3e60
本文出自 “子 孑” 博客,请务必保留此出处http://zhangjunhd.blog.51cto.com/113473/126545
相关文章推荐
- 【华为OJ】【106-Sudoku-Java】
- eclipse 安卓开发环境搭建
- java中的命名规范
- eclipse开发时常用的快捷键
- JavaWeb会话管理:(2)Session
- Atitit.mybatis的测试 以及spring与mybatis在本项目中的集成配置说明
- Atitit.mybatis的测试 以及spring与mybatis在本项目中的集成配置说明
- Atitit.mybatis的测试 以及spring与mybatis在本项目中的集成配置说明
- 一个简单的rpc框架实现(待连载优化)
- 使用场景
- java泛型程序设计之泛型方法
- java泛型程序设计之泛型类
- Java中普通代码块,构造代码块,静态代码块区别及代码示例
- Java基础回顾 : RuntimeException和Exception的区别
- 一、初识java
- AutoCloseable,Closeable和Flushable
- JSP+Servlet制作Java Web登录功能的全流程解析
- Java Web开发过程中登陆模块的验证码的实现方式总结
- Spring定时任务的几种实现
- Java Switch语句及性能剖析(转载补充)