1. 程式人生 > >模擬spring的注入和讀取配置檔案(ApplicationContext.xml)

模擬spring的注入和讀取配置檔案(ApplicationContext.xml)

場景:使用者新增到資料庫中

傳統方式儲存例項3個問題:

1/改動資料儲存方式,如儲存到XML檔案中會造成程式變更

2/UserService無法在單例項情況下被重用,因為它的宣告在test.java

3/UserService引用其它資源不便

  1. package com.bjsxt.dao;  
  2. import com.bjsxt.model.User;  
  3. publicinterface UserDAO {  
  4.     publicvoid save(User user);  
  5. }  
  1. package com.bjsxt.dao.impl;  
  2. import com.bjsxt.dao.UserDAO;  
  3. import com.bjsxt.model.User;  
  4. publicclass UserDAOImpl implements UserDAO {  
  5.     publicvoid save(User user) {  
  6.         //Hibernate
  7.         //JDBC
  8.         //XML
  9.         //NetWork
  10.         System.out.println("資料儲存進資料庫:user " + user.getUsername()+" saved!");  
  11.     }  
  12. }  

Bean.xml配置檔案

  1. <beans>
  2.     <
    beanid="u"class="com.bjsxt.dao.impl.UserDAOImpl"/>
  3.     <beanid="userService"class="com.bjsxt.service.UserService">
  4.         <propertyname="userDAO"bean="u"/>
  5.     </bean>
  6. </beans>

BeanFactory介面

  1. package com.bjsxt.spring;  
  2. //BeanFactory介面取得相對應的Bean物件引用
  3. publicinterface BeanFactory {  
  4.     public Object getBean(String id);  
  5. }  

模擬ClassPathXmlApplicationContext()取得

  1. package com.bjsxt.spring;  
  2. import java.lang.reflect.Method;  
  3. import java.util.HashMap;  
  4. import java.util.List;  
  5. import java.util.Map;  
  6. import org.jdom.Document;  
  7. import org.jdom.Element;  
  8. import org.jdom.input.SAXBuilder;  
  9. // jdom讀取xml檔案
  10. publicclass ClassPathXmlApplicationContext implements BeanFactory {  
  11.     private Map<String , Object> beans = new HashMap<String, Object>();  
  12.     //IOC Inverse of Control DI Dependency Injection
  13.     public ClassPathXmlApplicationContext() throws Exception {  
  14.         SAXBuilder sb=new SAXBuilder();  
  15.         Document doc=sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml")); //構造文件物件
  16.         Element root=doc.getRootElement(); //獲取根元素
  17.         List list=root.getChildren("bean");//取名字為bean的所有元素
  18.         for(int i=0;i<list.size();i++){  
  19.            Element element=(Element)list.get(i);  
  20.            String id=element.getAttributeValue("id");  
  21.            String clazz=element.getAttributeValue("class");  
  22.            Object o = Class.forName(clazz).newInstance();  
  23.            System.out.println("BeanId = " + id);  
  24.           System.out.println("ClassName = " + className);          beans.put(id, o);  
  25.            for(Element propertyElement : (List<Element>)element.getChildren("property")) {  
  26.                String name = propertyElement.getAttributeValue("name"); //userDAO
  27.                String bean = propertyElement.getAttributeValue("bean"); //u
  28.                Object beanObject = beans.get(bean);//UserDAOImpl instance
  29.                String methodName = "set" + name.substring(01).toUpperCase() + name.substring(1);  
  30.                System.out.println("method name = " + methodName);  
  31.                Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);  
  32.                m.invoke(o, beanObject);  
  33.            }  
  34.         }    
  35.     }  
  36.     public Object getBean(String id) {  
  37.         return beans.get(id);  
  38.     }  
  39. }  
  1. package com.bjsxt.service;  
  2. import org.junit.Test;  
  3. import com.bjsxt.dao.UserDAO;  
  4. import com.bjsxt.model.User;  
  5. import com.bjsxt.spring.BeanFactory;  
  6. import com.bjsxt.spring.ClassPathXmlApplicationContext;  
  7. publicclass UserServiceTest {  
  8.     @Test
  9.     publicvoid testAdd() throws Exception {  
  10. //Spring IoC容器的例項化非常簡單
  11.         BeanFactory applicationContext = new ClassPathXmlApplicationContext();  
  12.         UserService service = (UserService)applicationContext.getBean("userService");  
  13.         User u = new User();  
  14.         u.setUsername("zhangsan");  
  15.         u.setPassword("zhangsan");  
  16.         service.add(u);  
  17.     }  
  18. }  

jdom讀取結果和輸出儲存結果

BeanId = u

ClassName = com.bjsxt.dao.impl.UserDAOImpl

BeanId = userService

ClassName = com.bjsxt.service.UserService

method name = setUserDAO

資料儲存進資料庫:user zhangsan saved!

思考:

BeanFactory與ApplicationContext兩介面的比較(用哪個?)

1、功能:

更強大:子介面ApplicationContext提供了更多的附加功能,如:Web整合,支援國際化、事件釋出通知等功能。

2、在類建立時間上的不同:

BeanFactory取得Bean是延遲取得,即第一次使用getBean()方法時才建立指定類的物件;

ApplicationContext取得Bean的例項是在自身被視窗初始化的時候就建立全部的類物件了。

//Spring IoC容器的例項化非常簡單

       BeanFactory applicationContext =newClassPathXmlApplicationContext();

等價

ApplicationContext ctx = newClassPathXmlApplicationContext();