模擬實現IoC容器

       Spring的IoC核心就是控制反轉,將對實現對象的操做控制器交出來,由IoC容器來管理,從配置文件中獲取配置信息,Java對XML文檔提供了完美的支持,dom4j功能強大,而下面我就用JDOM這一開源項目,利用它能夠純Java技術實現對XML文檔的解析、生成、序列化來模擬實現IoC容器。

 1、傳統方式完成項目。
        1.定義接口java

package com.decipher.car; public interface Car { public String getBrand(); public void run(); }


2.接下來實現Car接口程序員

package com.decipher.carImplementation;
import com.decipher.car.Car;
public class BMWCar implements Car{
    private String MyBrand="寶馬";
    public String getBrand(){
        return MyBrand;
    }
    public void run(){
        System.out.println(MyBrand+" is runing");
    }
}


3.新建一個Human類spring

package com.decipher.human;
import com.decipher.car.Car;
public class Human {
    private Car car;

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }
    public void myCarRun(){
        car.run();
    }
}


4.最後編寫測試類編程

package com.decipher.humen;

import com.decipher.car.Car;
import com.decipher.carImplementation.BMWCar;
import com.decipher.human.Human;

public class HumenTest {
    public static void main(String[] args) throws Exception {
        Human human=new Human();
        Car car=new BMWCar();
        human.setCar(car);
        human.myCarRun();    
    }
}

 


5.運行結果如圖:



二.JDOM模擬IoC容器反轉控制
在編程以前要導入jdom.jar包到項目工程目錄中。
1.新建BeanFactorydom

package com.decipher.spring;

public interface BeanFactory {
    public Object getBean(String id);
}

 


2.實現BeanFactory接口測試

package com.decipher.spring;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

public class ClassPathXmlApplicationContext {
    //儲存各個實例的鍵值對
    private Map<String,Object> beans=new HashMap<String,Object>();
    //構造方法
    public ClassPathXmlApplicationContext() throws Exception{
        //讀取XML文檔
        SAXBuilder sb=new SAXBuilder();
        //構造文檔對象DOC
        Document doc=sb.build(this.getClass().getClassLoader().getResource("beans.xml"));
        //獲取XML文檔根元素
        Element root=doc.getRootElement();
        //獲取根元素下全部的子元素
        List list=root.getChildren("bean");
        //遍歷全部的Bean元素
        for(int i=0;i<list.size();i++){
            //取得第i個Bean元素
            Element element=(Element)list.get(i);
            //獲取第i個Bean元素的id屬性值,並將其存入到字符串變量id中
            String id=element.getAttributeValue("id");
            //獲取第i個Bean元素的class屬性值,並將其存入到字符串變量clazz中
            String clazz=element.getAttributeValue("class");
            //使用反射生成類的對象,至關於生成類對象,且存儲在Map中
            Object o=Class.forName(clazz).newInstance();
            System.out.println(id);
            System.out.println(clazz);
            beans.put(id,o);//將id和對象o存入Map中
            //對第i個bean元素下的每一個property子元素進行遍歷
            for(Element propertyElement:(List<Element>)element.getChildren("property")){
                //獲取property元素的name屬性值
                String name=propertyElement.getAttributeValue("name");
                //獲取property元素的bean屬性值
                String beanInstance=propertyElement.getAttributeValue("bean");
                //取得被注入對象的實例
                Object beanObject=beans.get(beanInstance);
                //獲取setter方法的方法名,形式爲setXxx
                String methodName="set"+name.substring(0, 1).toUpperCase()+name.substring(1);
                System.out.println("method name= "+methodName);
                //使用反射取得指定名稱,指定參數類型的setXxx方法
                Method m=o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);
                //調用對象o的setXxx方法
                m.invoke(o,beanObject);
            }
        }
    }
        public Object getBean(String id){
            return beans.get(id);
        }
}

 


3.配置beans.xml文件ui

<beans>
    <bean id="baomacar" class="com.decipher.carImplementation.BMWCar">
    </bean>
    <bean id="human" class="com.decipher.human.Human">
        <property name="car" bean="baomacar"></property>
    </bean>
</beans>

 


4.編寫測試類HumenTestthis

package com.decipher.humen;

import com.decipher.spring.ClassPathXmlApplicationContext;
import com.decipher.car.Car;
import com.decipher.carImplementation.BMWCar;
import com.decipher.human.Human;

public class HumenTest {
    public static void main(String[] args) throws Exception {    
        ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext();
        Human human=(Human)ctx.getBean("human");
        human.myCarRun();
    }
}

 


5.運行如圖:
spa

6.總結
    從上面的兩種實例化對象能夠看出,傳統的方式中,由程序員管理類對象,而在模擬的IoC容器中,將對類對象操做的控制器移交給IoC容器,由Ioc容器中的ApplicationContext處理XML配置文件,XML文件中每配置一個bean,即存儲在Map中,不須要程序員再new一個對象,而直接從容器中獲取便可,控制反轉能夠鬆耦,交出控制權利。

code

相關文章
相關標籤/搜索