国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Spring實現一個簡單的SpringIOC容器

Spring實現一個簡單的SpringIOC容器

2020-09-11 10:23醉眼識朦朧 Java教程

本篇文章主要介紹了Spring實現一個簡單的SpringIOC容器,具有一定的參考價值,感興趣的小伙伴們可以參考一下。

接觸spring快半年了,前段時間剛用spring4+s2h4做完了自己的畢設,但是很明顯感覺對spring尤其是ioc容器的實現原理理解的不到位,說白了,就是僅僅停留在會用的階段,有一顆想讀源碼的心于是買了一本計文柯的《spring技術內幕》,第二章沒看完,就被我扔一邊了,看的那是相當痛苦,深深覺得自己資質尚淺,能力還不夠,昨天在網上碰巧看到一個實現簡單的springioc容器的視頻教程,于是跟著做了一遍,竟然相當順利,至少每一行代碼都能理解,于是細心整理了一番,放在這里.

主要思想:

提到ioc,第一反應就是控制反轉,我以前以為springioc就是控制反轉,控制反轉就是springioc,當然這種理解是錯誤的,控制反轉是一種思想,一種模式,而spring的ioc容器是實現了這種思想這種模式的一個載體.

使用過spring的人都熟知,springioc容器可以在對象生成或初始化時就直接將數據注入到對象中,如果對象a的屬性是另一個對象b,還可以將這個對象b的引用注入到注入到a的數據域中.

如果在初始化對象a的時候,對象b還沒有進行初始化,而a又需要對象b作為自己的屬性,那么就會用一種遞歸的方式進行注入,這樣就可以把對象的依賴關系清晰有序的建立起來.

ioc容器解決問題的核心就是把創建和管理對象的控制權從具體的業務對象手中搶過來.由ioc容器來管理對象之間的依賴關系,并由ioc容器完成對象的注入.這樣就把應用從復雜的對象依賴關系的管理中解放出來,簡化了程序的開發過程.

下圖是這個簡單ioc容器的類圖(原諒我真沒學過uml,湊合看吧):

Spring實現一個簡單的SpringIOC容器

程序中所有的bean之間的依賴關系我們是放在一個xml文件中進行維護的,就是applicationcontext.xml  

configmanager類完成的功能是讀取xml,并將所有讀取到有用的信息封裝到我們創建的一個map<string,bean>集合中,用來在初始化容器時創建bean對象.

定義一個beanfactory的接口,接口中有一個getbean(string name)方法,用來返回你想要創建的那個對象.

然后定義一個該接口的實現類classpathxmlapplicationcontext.就是在這個類的構造方法中,初始化容器,通過調用configmanager的方法返回的map集合,通過反射和內省一一創建bean對象.這里需要注意,對象的創建有兩個時間點,這取決與bean標簽中scope屬性的值:  

  1. 如果scope="singleton",那么對象在容器初始化時就已創建好,用的時候只需要去容器中取即可.
  2. 如果scope="prototype",那么容器中不保存這個bean的實例對象,每次開發者需要使用這個對象時再進行創建.

使用的主要知識點:

  1. dom4j解析xml文件
  2. xpath表達式(用于解析xml中的標簽)
  3. java反射機制
  4. 內省(獲取bean屬性的set方法進行賦值)

項目結構圖及介紹如下:

Spring實現一個簡單的SpringIOC容器         

項目需要的jar包與項目結構已經在上圖中介紹了,這個項目所能實現的功能如下:

1. ioc容器能管理對象的創建以及對象之間的依賴關系.

2. 能夠實現數據的自動類型轉換(借助beanutils).

3. 能夠實現scope="singleton"和scope="prototype"的功能,即能夠控制對象是否為單例.  

下面介紹代碼部分:

application.xml:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="utf-8"?>
<beans>
  <bean name="student" class="com.wang.entity.student" >
    <property name="name" value="123"></property>
  </bean>
  
  <bean name="teacher" class="com.wang.entity.teacher">
    <property name="student" ref="student"></property>
  </bean>
  <bean name="person" class="com.wang.entity.person" scope="prototype">
    <property name="teacher" ref="teacher"></property>
    <property name="student" ref="student"></property>
  </bean>
  
</beans>

實體類student,teacher,person:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.wang.entity;
//student類
public class student {
  private string name;
 
  public string getname() {
    return name;
  }
 
  public void setname(string name) {
    this.name = name;
  }
}
/************************************/
package com.wang.entity;
//teacher類
public class teacher {
 
  private student student;
 
  public student getstudent() {
    return student;
  }
 
  public void setstudent(student student) {
    this.student = student;
  }
   
}
/************************************/
package com.wang.entity;
//person類
public class person {
 
  private student student;
  private teacher teacher;
  
  public student getstudent() {
    return student;
  }
  public void setstudent(student student) {
    this.student = student;
  }
  public teacher getteacher() {
    return teacher;
  }
  public void setteacher(teacher teacher) {
    this.teacher = teacher;
  }
}

用于封裝bean標簽信息的bean類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package com.wang.config;
 
import java.util.arraylist;
import java.util.list;
 
public class bean {
 
  
  private string name;
  private string classname;
  private string scope="singleton";
  private list<property> properties=new arraylist<property>();
 
  
  public string getscope() {
    return scope;
  }
 
  public void setscope(string scope) {
    this.scope = scope;
  }
 
  public string getname() {
    return name;
  }
 
  public void setname(string name) {
    this.name = name;
  }
 
  public string getclassname() {
    return classname;
  }
 
  public void setclassname(string classname) {
    this.classname = classname;
  }
 
  public list<property> getproperties() {
    return properties;
  }
 
  public void setproperties(list<property> properties) {
    this.properties = properties;
  }
 
  
}

用與封裝bean子標簽property內容的property類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.wang.config;
 
public class property {
 
  private string name;
  private string value;
  private string ref;
  public string getname() {
    return name;
  }
  public void setname(string name) {
    this.name = name;
  }
  public string getvalue() {
    return value;
  }
  public void setvalue(string value) {
    this.value = value;
  }
  public string getref() {
    return ref;
  }
  public void setref(string ref) {
    this.ref = ref;
  }
 
  
}

configmanager類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package com.wang.config.parse;
 
import java.io.inputstream;
import java.util.hashmap;
import java.util.list;
import java.util.map;
 
import org.dom4j.document;
import org.dom4j.documentexception;
import org.dom4j.element;
import org.dom4j.io.saxreader;
import org.junit.test;
 
import com.wang.config.bean;
import com.wang.config.property;
 
public class configmanager {
  
  private static map<string,bean> map=new hashmap<string,bean>();
 
  //讀取配置文件并返回讀取結果
  //返回map集合便于注入,key是每個bean的name屬性,value是對應的那個bean對象
  public static map<string, bean> getconfig(string path){
    /*dom4j實現
     * 1.創建解析器
     * 2.加載配置文件,得到document對象
     * 3.定義xpath表達式,取出所有bean元素
     * 4.對bean元素繼續遍歷
     *   4.1將bean元素的name/class屬性封裝到bean類屬性中
     *   4.2獲得bean下的所有property子元素
     *   4.3將屬性name/value/ref分裝到類property類中
     * 5.將property對象封裝到bean對象中
     * 6.將bean對象封裝到map集合中,返回map
      */
    //1.創建解析器
    saxreader reader=new saxreader();
    //2.加載配置文件,得到document對象
    inputstream is = configmanager.class.getresourceasstream(path);
    document doc =null;
    try {
       doc = reader.read(is);
    } catch (documentexception e) {
      e.printstacktrace();
      throw new runtimeexception("請檢查您的xml配置是否正確");
    }
    // 3.定義xpath表達式,取出所有bean元素
    string xpath="//bean";
    
    //4.對bean元素繼續遍歷
    list<element> list = doc.selectnodes(xpath);
    if(list!=null){
      //4.1將bean元素的name/class屬性封裝到bean類屬性中
    
       // 4.3將屬性name/value/ref分裝到類property類中
      for (element bean : list) {
        bean b=new bean();
        string name=bean.attributevalue("name");
        string clazz=bean.attributevalue("class");
        string scope=bean.attributevalue("scope");
        b.setname(name);
        b.setclassname(clazz);
        if(scope!=null){
          b.setscope(scope);
        }
         // 4.2獲得bean下的所有property子元素
        list<element> children = bean.elements("property");
        
         // 4.3將屬性name/value/ref分裝到類property類中
        if(children!=null){
          for (element child : children) {
            property prop=new property();
            string pname=child.attributevalue("name");
            string pvalue=child.attributevalue("value");
            string pref=child.attributevalue("ref");
            prop.setname(pname);
            prop.setref(pref);
            prop.setvalue(pvalue);
            // 5.將property對象封裝到bean對象中
            b.getproperties().add(prop);
          }
        }
        //6.將bean對象封裝到map集合中,返回map
        map.put(name, b);
      }
    }
    
    return map;
  }
 
}

 beanfactory接口:

?
1
2
3
4
5
6
package com.wang.main;
 
public interface beanfactory {
  //核心方法getbean
  object getbean(string name);
}

classpathxmlapplicationcontext類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package com.wang.main;
 
import java.lang.reflect.invocationtargetexception;
import java.lang.reflect.method;
import java.util.hashmap;
import java.util.map;
import java.util.map.entry;
 
import org.apache.commons.beanutils.beanutils;
import org.junit.test;
 
import com.wang.config.bean;
import com.wang.config.property;
import com.wang.config.parse.configmanager;
import com.wang.entity.student;
//import com.wang.utils.beanutils;
import com.wang.utils.beanutil;
 
public class classpathxmlapplicationcontext implements beanfactory {
 
  // 獲得讀取的配置文件中的map信息
  private map<string, bean> map;
  // 作為ioc容器使用,放置sring放置的對象
  private map<string, object> context = new hashmap<string, object>();
 
  public classpathxmlapplicationcontext(string path) {
    // 1.讀取配置文件得到需要初始化的bean信息
    map = configmanager.getconfig(path);
    // 2.遍歷配置,初始化bean
    for (entry<string, bean> en : map.entryset()) {
      string beanname = en.getkey();
      bean bean = en.getvalue();
 
      object existbean = context.get(beanname);
      // 當容器中為空并且bean的scope屬性為singleton時
      if (existbean == null && bean.getscope().equals("singleton")) {
        // 根據字符串創建bean對象
        object beanobj = createbean(bean);
 
        // 把創建好的bean對象放置到map中去
        context.put(beanname, beanobj);
      }
    }
 
  }
 
  // 通過反射創建對象
  private object createbean(bean bean) {
    // 創建該類對象
    class clazz = null;
    try {
      clazz = class.forname(bean.getclassname());
    } catch (classnotfoundexception e) {
      e.printstacktrace();
      throw new runtimeexception("沒有找到該類" + bean.getclassname());
    }
    object beanobj = null;
    try {
      beanobj = clazz.newinstance();
    } catch (exception e) {
      e.printstacktrace();
      throw new runtimeexception("沒有提供無參構造器");
    }
    // 獲得bean的屬性,將其注入
    if (bean.getproperties() != null) {
      for (property prop : bean.getproperties()) {
        // 注入分兩種情況
        // 獲得要注入的屬性名稱
        string name = prop.getname();
        string value = prop.getvalue();
        string ref = prop.getref();
        // 使用beanutils工具類完成屬性注入,可以自動完成類型轉換
        // 如果value不為null,說明有
        if (value != null) {
          map<string, string[]> parmmap = new hashmap<string, string[]>();
          parmmap.put(name, new string[] { value });
          try {
            beanutils.populate(beanobj, parmmap);
          } catch (exception e) {
            e.printstacktrace();
            throw new runtimeexception("請檢查你的" + name + "屬性");
          }
        }
 
        if (ref != null) {
          // 根據屬性名獲得一個注入屬性對應的set方法
          // method setmethod = beanutil.getwritemethod(beanobj,
          // name);
 
          // 看一看當前ioc容器中是否已存在該bean,有的話直接設置沒有的話使用遞歸,創建該bean對象
          object existbean = context.get(prop.getref());
          if (existbean == null) {
            // 遞歸的創建一個bean
            existbean = createbean(map.get(prop.getref()));
            // 放置到context容器中
            // 只有當scope="singleton"時才往容器中放
            if (map.get(prop.getref()).getscope()
                .equals("singleton")) {
              context.put(prop.getref(), existbean);
            }
          }
          try {
            // setmethod.invoke(beanobj, existbean);
              //通過beanutils為beanobj設置屬性
            beanutils.setproperty(beanobj, name, existbean);
          } catch (exception e) {
            e.printstacktrace();
            throw new runtimeexception("您的bean的屬性" + name
                + "沒有對應的set方法");
          }
 
        }
 
      }
    }
 
    return beanobj;
  }
 
  @override
  public object getbean(string name) {
    object bean = context.get(name);
    // 如果為空說明scope不是singleton,那么容器中是沒有的,這里現場創建
    if (bean == null) {
      bean = createbean(map.get(name));
    }
 
    return bean;
  }
 
}

最后就是一個測試類testbean:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.wang.main;
 
import org.junit.test;
 
import com.wang.entity.person;
import com.wang.entity.student;
import com.wang.entity.teacher;
 
 
public class testbean {
 
  @test
  public void func1(){
    
    beanfactory bf=new classpathxmlapplicationcontext("/applicationcontext.xml");
    person s=(person)bf.getbean("person");
    person s1=(person)bf.getbean("person");
    system.out.println(s==s1);
    system.out.println(s1);
    student stu1=(student) bf.getbean("student");
    student stu2=(student) bf.getbean("student");
    string name=stu1.getname();
    system.out.println(name);
    system.out.println(stu1==stu2);
  }
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://www.cnblogs.com/fingerboy/p/5425813.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美日韩视频在线 | 中文字幕 亚洲一区 | 久久亚洲综合 | 天天干女人网 | 国产亚洲精品美女久久久久久久久久 | 国产精品一区二区av | 久久久久久一区二区三区 | 亚洲h视频 | 日韩在线中文 | 免看一级一片 | 91免费在线视频 | 亚洲综合区 | 天天干天天操 | 午夜av影院 | 九九久久久 | 亚洲一区电影 | 欧美日韩免费在线 | 亚洲不卡在线 | 久久国产精品久久 | 久操视频免费在线观看 | 99精品视频在线观看 | 欧美日韩精品免费 | 亚洲一区二区在线 | 成人片免费看 | 欧美中文字幕在线 | 自拍偷拍精品 | 亚洲一区二区国产 | 一区视频在线 | 精品黄色国产 | 欧美成人a| 色噜噜狠狠一区二区三区狼国成人 | 国产高清精品一区 | av网站观看| 女教师高潮叫床视频在线观看 | 精品国产一区二区三区四区 | 日韩午夜 | 国产成人在线看 | 日本精品一区二 | 日韩在线看片 | 中文字幕啪啪 | 国产成人精品久久二区二区91 |