天天看點

Java代碼實作依賴注入

配置檔案setting.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans>

    <bean id="me" class="com.zj.ioc.di.imp.Person">

       <property name="name">

           <value>ZJ</value>

       </property>

       <property name="age">

           <value>26</value>

       <property name="height">

           <value>1.78</value>

    </bean>

    <bean id="you" class="com.zj.ioc.di.imp.Person">

           <value>Mary</value>

           <value>27</value>

           <value>1.66</value>

    <bean id="myList" class="com.zj.ioc.di.imp.ListOne">

       <property name="msg">

           <list>

              <value>java</value>

              <value>c</value>

              <value>windows</value>

           </list>

    <bean id="mySet" class="com.zj.ioc.di.imp.SetOne">

           <set>

              <value>tom</value>

              <value>cat</value>

              <value>dog</value>

           </set>

    <bean id="myMap" class="com.zj.ioc.di.imp.MapOne">

           <map>

              <entry key="c">

                  <value>CHINA</value>

              </entry>

              <entry key="j">

                  <value>JAPAN</value>

              <entry key="k">

                  <value>KOREA</value>

           </map>

    <bean id="us" class="com.zj.ioc.di.imp.Persons">

       <property name="i">

           <ref bean="me" />

       <property name="u">

           <ref bean="you" />

</beans>

依據setting.xml,這裡将建構兩個Person類的執行個體me和you:

Person.java

<b>package</b> com.zj.ioc.di.imp;

<b>public</b> <b>class</b> Person {

    <b>private</b> String name;

    <b>private</b> <b>int</b> age;

    <b>private</b> <b>float</b> height;

    <b>public</b> String getName() {<b>return</b> name;}

    <b>public</b> <b>void</b> setName(String name) {<b>this</b>.name = name;}

    <b>public</b> <b>int</b> getAge() {<b>return</b> age;}

    <b>public</b> <b>void</b> setAge(<b>int</b> age) {<b>this</b>.age = age;}

    <b>public</b> <b>float</b> getHeight() {<b>return</b> height;}

    <b>public</b> <b>void</b> setHeight(<b>float</b> height) {<b>this</b>.height = height;}

}

緊接着,建構一個ListOne的執行個體myList:

ListOne.java

<b>import</b> java.util.List;

<b>public</b> <b>class</b> ListOne {

    <b>private</b> List&lt;String&gt; msg;

    <b>public</b> List&lt;String&gt; getMsg() {<b>return</b> msg;}

    <b>public</b> <b>void</b> setMsg(List&lt;String&gt; msg) {<b>this</b>.msg = msg;}

緊接着,建構一個SetOne的執行個體mySet:

SetOne.java

<b>import</b> java.util.Set;

<b>public</b> <b>class</b> SetOne {

    <b>private</b> Set&lt;String&gt; msg;

    <b>public</b> Set&lt;String&gt; getMsg() {<b>return</b> msg;}

    <b>public</b> <b>void</b> setMsg(Set&lt;String&gt; msg) {<b>this</b>.msg = msg;}

緊接着,建構一個MapOne的執行個體myMap:

MapOne.java

<b>import</b> java.util.Map;

<b>public</b> <b>class</b> MapOne {

    <b>private</b> Map&lt;String,String&gt; msg;

    <b>public</b> Map&lt;String, String&gt; getMsg() {<b>return</b> msg;}

    <b>public</b> <b>void</b> setMsg(Map&lt;String, String&gt; msg) {<b>this</b>.msg = msg;}

最後建構一個Persons類的執行個體us,其中包含me和you兩個已經建構好的對象:

Persons.java

<b>public</b> <b>class</b> Persons {

    <b>private</b> Person i;

    <b>private</b> Person u;

    <b>public</b> Person getI() {<b>return</b> i;}

    <b>public</b> <b>void</b> setI(Person i) {<b>this</b>.i = i;}

    <b>public</b> Person getU() {<b>return</b> u;}

    <b>public</b> <b>void</b> setU(Person u) {<b>this</b>.u = u;}

主要的實作機制是(代碼BeanFactory.java以及工程見附件),

1.通過一個HashMap儲存構造好的對象,key就是bean的id屬性,value就是這個對象;

<b>private</b> Map&lt;String, Object&gt; beanMap = <b>new</b> HashMap&lt;String, Object&gt;();

……

<b>public</b> Object getBean(String beanId) {

    Object obj = beanMap.get(beanId);

    <b>return</b> obj;

查詢時

BeanFactory factory = <b>new</b> BeanFactory();

factory.init("setting.xml");

Person p1 = (Person) factory.getBean("me");

2.init方法讀入配置檔案setting.xml,并直接定位到beans下的bean元素,并執行個體化一個ElementHandler對其處理。

<b>public</b> <b>void</b> init(String xmlUri) <b>throws</b> Exception {

    SAXReader saxReader = <b>new</b> SAXReader();

    File file = <b>new</b> File(xmlUri);

    <b>try</b> {

       saxReader.addHandler("/beans/bean", <b>new</b> BeanHandler());

       saxReader.read(file);

    } <b>catch</b> (DocumentException e) {

       System.out.println(e.getMessage());

    }

3.ElementHandler,dom4j的ElementHandler接口有兩個方法,一個是onStart(),它主要用于處理該元素的屬性以及動态增加新的Handler類;另一個是onEnd(),它主要用于獲得該元素的Text文本以及删除已添加的Handler。

BeanHandler

<b>private</b> <b>class</b> BeanHandler <b>implements</b> ElementHandler {

    Object obj = <b>null</b>;

    <b>public</b> <b>void</b> .Start(ElementPath path) {

       Element beanElement = path.getCurrent();

       Attribute classAttribute = beanElement.attribute("class");

       Class&lt;?&gt; bean = <b>null</b>;

       <b>try</b> {

           bean = Class.forName(classAttribute.getText());

       } <b>catch</b> (ClassNotFoundException e) {

           e.printStackTrace();

       }

       Field fields[] = bean.getDeclaredFields();

       Map&lt;String, Field&gt; mapField = <b>new</b> HashMap&lt;String, Field&gt;();

       <b>for</b> (Field field : fields)

           mapField.put(field.getName(), field);

           obj = bean.newInstance();

       } <b>catch</b> (InstantiationException e) {

       } <b>catch</b> (IllegalAccessException e) {

       path.addHandler("property", <b>new</b> PropertyHandler(mapField, obj));

    <b>public</b> <b>void</b> .End(ElementPath path) {

       Attribute idAttribute = beanElement.attribute("id");

       beanMap.put(idAttribute.getText(), obj);

       path.removeHandler("property");

PropertyHandler

<b>private</b> <b>class</b> PropertyHandler <b>implements</b> ElementHandler {

    Map&lt;String, Field&gt; mapField;

    Object obj;

    <b>public</b> PropertyHandler(Map&lt;String, Field&gt; mapField, Object obj) {

       <b>this</b>.mapField = mapField;

       <b>this</b>.obj = obj;

       Element propertyElement = path.getCurrent();

       Attribute nameAttribute = propertyElement.attribute("name");

       path.addHandler("value", <b>new</b> ValueHandler(mapField, obj,

              nameAttribute));

       path.addHandler("list", <b>new</b> ListHandler(mapField, obj,

       path.addHandler("set", <b>new</b> SetHandler(mapField, obj,

       path.addHandler("map", <b>new</b> MapHandler(mapField, obj,

       path.addHandler("ref", <b>new</b> RefHandler(mapField, obj,

       path.removeHandler("value");

       path.removeHandler("list");

       path.removeHandler("set");

       path.removeHandler("map");

       path.removeHandler("ref");

根據setting.xml,我們可以得到各種注入元素的Handler類處理流程圖。

4. setFieldValue()基于反射機制和相應的類資訊得到Field的類型,并根據setting.xml設定它的值。

<b>private</b> <b>void</b> setFieldValue(Object obj, Field field, String value) {

    String fieldType = field.getType().getSimpleName();

       <b>if</b> (fieldType.equals("int"))

           field.setInt(obj, <b>new</b> Integer(value));

       <b>else</b> <b>if</b> (fieldType.equals("float"))

           field.setFloat(obj, <b>new</b> Float(value));

       <b>else</b> <b>if</b> (fieldType.equals("boolean"))

           field.setBoolean(obj, <b>new</b> Boolean(value));

       <b>else</b> <b>if</b> (fieldType.equals("char"))

           field.setChar(obj, value.charAt(0));

       <b>else</b> <b>if</b> (fieldType.equals("double"))

           field.setDouble(obj, <b>new</b> Double(value));

       <b>else</b> <b>if</b> (fieldType.equals("long"))

           field.setLong(obj, <b>new</b> Long(value));

       <b>else</b>

           field.set(obj, value);

    } <b>catch</b> (IllegalArgumentException e) {

       e.printStackTrace();

    } <b>catch</b> (IllegalAccessException e) {

<b>private</b> <b>void</b> setFieldValue(Object obj, Field field, List&lt;String&gt; value) {

       field.set(obj, value);

5.測試

<b>public</b> <b>static</b> <b>void</b> main(String[] args) {

       BeanFactory factory = <b>new</b> BeanFactory();

       factory.init("setting.xml");

       Person p1 = (Person) factory.getBean("me");

       System.out.print(p1.getName() + " ");

       System.out.print(p1.getAge() + " ");

       System.out.println(p1.getHeight());

       Person p2 = (Person) factory.getBean("you");

       System.out.print(p2.getName() + " ");

       System.out.print(p2.getAge() + " ");

       System.out.println(p2.getHeight());

       ListOne list = (ListOne) factory.getBean("myList");

       System.out.println(list.getMsg());

       SetOne set = (SetOne) factory.getBean("mySet");

       System.out.println(set.getMsg());

       MapOne map = (MapOne) factory.getBean("myMap");

       System.out.println(map.getMsg());

       Persons us = (Persons) factory.getBean("us");

       System.out.println(us.getI());

       System.out.println(us.getU());

    } <b>catch</b> (Exception e) {

測試結果:

ZJ 26 1.78

Mary 27 1.66

[java, c, windows]

[cat, tom, dog]

{c=CHINA, j=JAPAN, k=KOREA}

com.zj.ioc.di.imp.Person@1a5ab41

com.zj.ioc.di.imp.Person@18e3e60

本文轉自zhangjunhd51CTO部落格,原文連結:http://blog.51cto.com/zhangjunhd/126545,如需轉載請自行聯系原作者