模擬spring的注入和讀取配置檔案(ApplicationContext.xml)
阿新 • • 發佈:2019-01-01
場景:使用者新增到資料庫中
傳統方式儲存例項3個問題:
1/改動資料儲存方式,如儲存到XML檔案中會造成程式變更
2/UserService無法在單例項情況下被重用,因為它的宣告在test.java中
3/UserService引用其它資源不便
- package com.bjsxt.dao;
- import com.bjsxt.model.User;
- publicinterface UserDAO {
- publicvoid save(User user);
- }
- package com.bjsxt.dao.impl;
-
import com.bjsxt.dao.UserDAO;
- import com.bjsxt.model.User;
- publicclass UserDAOImpl implements UserDAO {
- publicvoid save(User user) {
- //Hibernate
- //JDBC
- //XML
- //NetWork
- System.out.println("資料儲存進資料庫:user " + user.getUsername()+" saved!");
- }
- }
Bean.xml配置檔案
- <beans>
-
<
- <beanid="userService"class="com.bjsxt.service.UserService">
- <propertyname="userDAO"bean="u"/>
- </bean>
- </beans>
BeanFactory介面
- package com.bjsxt.spring;
- //BeanFactory介面取得相對應的Bean物件引用
-
publicinterface BeanFactory {
- public Object getBean(String id);
- }
模擬ClassPathXmlApplicationContext()取得
- package com.bjsxt.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;
- // jdom讀取xml檔案
- publicclass ClassPathXmlApplicationContext implements BeanFactory {
- private Map<String , Object> beans = new HashMap<String, Object>();
- //IOC Inverse of Control DI Dependency Injection
- public ClassPathXmlApplicationContext() throws Exception {
- SAXBuilder sb=new SAXBuilder();
- Document doc=sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml")); //構造文件物件
- Element root=doc.getRootElement(); //獲取根元素
- List list=root.getChildren("bean");//取名字為bean的所有元素
- for(int i=0;i<list.size();i++){
- Element element=(Element)list.get(i);
- String id=element.getAttributeValue("id");
- String clazz=element.getAttributeValue("class");
- Object o = Class.forName(clazz).newInstance();
- System.out.println("BeanId = " + id);
- System.out.println("ClassName = " + className); beans.put(id, o);
- for(Element propertyElement : (List<Element>)element.getChildren("property")) {
- String name = propertyElement.getAttributeValue("name"); //userDAO
- String bean = propertyElement.getAttributeValue("bean"); //u
- Object beanObject = beans.get(bean);//UserDAOImpl instance
- String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
- System.out.println("method name = " + methodName);
- Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);
- m.invoke(o, beanObject);
- }
- }
- }
- public Object getBean(String id) {
- return beans.get(id);
- }
- }
- package com.bjsxt.service;
- import org.junit.Test;
- import com.bjsxt.dao.UserDAO;
- import com.bjsxt.model.User;
- import com.bjsxt.spring.BeanFactory;
- import com.bjsxt.spring.ClassPathXmlApplicationContext;
- publicclass UserServiceTest {
- @Test
- publicvoid testAdd() throws Exception {
- //Spring IoC容器的例項化非常簡單
- BeanFactory applicationContext = new ClassPathXmlApplicationContext();
- UserService service = (UserService)applicationContext.getBean("userService");
- User u = new User();
- u.setUsername("zhangsan");
- u.setPassword("zhangsan");
- service.add(u);
- }
- }
jdom讀取結果和輸出儲存結果
|
思考:
BeanFactory與ApplicationContext兩介面的比較(用哪個?)
1、功能:
更強大:子介面ApplicationContext提供了更多的附加功能,如:Web整合,支援國際化、事件釋出通知等功能。
2、在類建立時間上的不同:
BeanFactory取得Bean是延遲取得,即第一次使用getBean()方法時才建立指定類的物件;
ApplicationContext取得Bean的例項是在自身被視窗初始化的時候就建立全部的類物件了。
//Spring IoC容器的例項化非常簡單 BeanFactory applicationContext =newClassPathXmlApplicationContext(); 等價 ApplicationContext ctx = newClassPathXmlApplicationContext(); |