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