1. 程式人生 > >1.IOC原理模擬

1.IOC原理模擬

method con set方法 span interface beans 實例化 asstream .get

Spring兩大核心功能,IOC(Inverse of Control) 和 AOP(Aspect-Oriented-Programming)

IOC原理模擬:

  有這樣一個beans.xml:

1 <beans>
2     <bean id="u" class="com.bjsxt.dao.impl.UserDAOImpl" />
3     <bean id="userService" class="com.bjsxt.service.UserService" >
4         <property name="userDAO" ref="u"/>
5
</bean> 6 7 </beans>

現在我們想讀取這個配置文件,實例化裏面所有的bean,將其放到我們的容器中

1. 首先我們的容器是一個 Map,裏面存放我們bean的實力對象

private Map<String,Object> beans = new HashMap<String,Object>();

2.開始解析這個配置文件

  a)讀取這個配置文件,先獲取這個配置文件的根節點,再獲取根節點下所有標簽名為 <bean> 的節點

1 Document doc = sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml")); //
構造文檔對象 2 Element root = doc.getRootElement(); //獲取根元素 3 List list = root.getChildren("bean"); //獲得根節點下所有標簽名為 bean 的節點

  b)遍歷所有的<bean>節點,拿到裏面的 id 屬性和 class屬性

for(int i=0;i<list.size();i++) {
            Element element=(Element)list.get(i);
            String id
=element.getAttributeValue("id"); String clazz=element.getAttributeValue("class");

  

  c)根據每個bean中的class屬性的值,創建這個類的一個實例,將這個實例對象作為 value,bean中的id屬性作為 key ,put進我們的容器中

Object o = Class.forName(clazz).newInstance();
beans.put(id, o);      //key 為 id 屬性,value為 class 屬性的實例

  d)遍歷所有的<bean>節點,判斷 <bean> 節點後面是否還有 <property>節點

   如果有的話,說明 這個bean中還需要註入其他實例對象 作為 屬性 註入給它,所以我們需要繼續去讀這個 <property>,拿到 <property> 的 name 屬性 和 ref屬性

for(Element propertyElement : (List<Element>)element.getChildren("property")) {            //如果某個bean中,存在property,即 存在 set***方法,則將xml文件指定的class註入進行
               String name = propertyElement.getAttributeValue("name");   //userDAO
               String ref= propertyElement.getAttributeValue("ref");   //u

  e)ref關聯的是 某個 bean的id,所以通過ref屬性,就可以 get 出 對應的實例對象,用於註入

 Object beanObject = beans.get(ref);                 //UserDAOImpl instance

  

  f)既然某個bean 希望 有 另外一個bean 可以註入進來,那麽肯定要有對應 set方法,這個時候就需要用到 name 屬性

  通過name屬性,得到 註入的位置,如這裏 name屬性的值是 userDAO,說明該bean 需要一個UserDAO 類型的屬性

  通過字符串拼接得到 setUserDAO方法,

String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);        //拼接成setUserDAO

  

  g)反射調用該方法,完成 bean 的註入

Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);   //反射調用 setUserDAO 方法,將userDao 註入 到 userService中
m.invoke(o, beanObject);

  h)外界調用

  當程序一啟動,就啟動我們的容器,讀取配置文件,完成bean 初始化和 註入,放到我們容器中

  UserService service = (UserService) applicationContext.getBean("userService");

  getBean方法,實際上就是 調用我們 容器(Map)的 get方法,通過 bean節點的id屬性,拿到對象bean的實例

1.IOC原理模擬