在建構tiny架構之初,想着是不是不要強依賴spring?于是就寫了一個類spring的依賴注入容器,基本實作了spring的依賴注入部分的功能,工作情況也良好,配置規範也是采用的spring的規範。在前面一直是沒有問題的,但是在做資料庫業務的時候,出現問題了。做資料庫,必須要考慮事務問題,而當時我的設計目标是對各種開源的ormapping方案都不拒絕,這個時候就引入一個問題,要麼自己再實作一套aop,要麼就複用spring。當時預想的另外一個方案是核心架構采用非直接依賴spring的方案,資料庫相關的采用spring依賴的方式。但是實際上,業務層面的bean會依賴系統層面的bean,這又涉及到兩個容器之間的協作,這個時候,我意識到,是應該做一個取舍了。
是以果斷放棄自己來做ioc和aop方面的工作,而采用強依賴spring來實作的方案,畢竟在現在的應用場景下,拒絕spring就等于讓别人拒絕自己。
但是,不管怎麼樣,在實作這個容器的過程中,還是讓我對依賴注入方面有了更深的了解,是以,這兩天的投入還是值得的。
下面展示一下,它實作的功能:
<a href="http://my.oschina.net/tinyframework/blog/170763#">?</a>
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
<code><beans></code>
<code> </code><code><bean id=</code><code>"user"</code> <code>name=</code><code>"user,user1,user2"</code> <code>scope=</code><code>"singleton"</code>
<code> </code><code>class</code><code>=</code><code>"org.tinygroup.factory.config.user"</code><code>></code>
<code> </code><code><property name=</code><code>"name"</code><code>></code>
<code> </code><code><value>aa</value></code>
<code> </code><code></property></code>
<code> </code><code><property name=</code><code>"age"</code><code>></code>
<code> </code><code><value></code><code>12</code><code></value></code>
<code> </code><code><property name=</code><code>"cat"</code><code>></code>
<code> </code><code><ref id=</code><code>"cat"</code> <code>/></code>
<code> </code><code><property name=</code><code>"cats"</code><code>></code>
<code> </code><code><list></code>
<code> </code><code><ref id=</code><code>"cat"</code> <code>/></code>
<code> </code><code></list></code>
<code> </code><code><property name=</code><code>"catset"</code><code>></code>
<code> </code><code><property name=</code><code>"catmap"</code><code>></code>
<code> </code><code><map></code>
<code> </code><code><entry key=</code><code>"aa"</code> <code>value-ref=</code><code>"cat"</code><code>></entry></code>
<code> </code><code></map></code>
<code> </code><code></bean></code>
<code> </code><code><bean id=</code><code>"cat"</code> <code>scope=</code><code>"singleton"</code> <code>class</code><code>=</code><code>"org.tinygroup.factory.config.cat"</code> <code>/></code>
<code> </code><code><bean id=</code><code>"cat1"</code> <code>scope=</code><code>"prototype"</code> <code>class</code><code>=</code><code>"org.tinygroup.factory.config.cat"</code> <code>/></code>
<code> </code><code><bean id=</code><code>"aaa1"</code> <code>scope=</code><code>"singleton"</code> <code>class</code><code>=</code><code>"org.tinygroup.factory.config.aaa"</code><code>></code>
<code> </code><code><value>aaa1</value></code>
<code> </code><code><bean id=</code><code>"aaa"</code> <code>scope=</code><code>"singleton"</code> <code>class</code><code>=</code><code>"org.tinygroup.factory.config.aaa"</code><code>></code>
<code> </code><code><value>aaa</value></code>
<code> </code><code><bean id=</code><code>"bbb"</code> <code>scope=</code><code>"singleton"</code> <code>class</code><code>=</code><code>"org.tinygroup.factory.config.bbb"</code>
<code> </code><code>autowire=</code><code>"bytype"</code> <code>/></code>
<code> </code><code><bean id=</code><code>"ccc"</code> <code>scope=</code><code>"singleton"</code> <code>class</code><code>=</code><code>"org.tinygroup.factory.config.ccc"</code>
<code> </code><code>autowire=</code><code>"byname"</code> <code>/></code>
<code> </code><code><bean id=</code><code>"user2"</code> <code>name=</code><code>"user,user1,user2"</code> <code>scope=</code><code>"prototype"</code>
<code> </code><code><value>aa1</value></code>
<code> </code><code><value></code><code>121</code><code></value></code>
<code> </code><code><ref id=</code><code>"cat1"</code> <code>/></code>
<code></beans></code>
可以看到,配置與spring是相容的。
下面是一些測試用例:
<code><span></span></code><code>public</code> <code>void</code> <code>testautoassemble() {</code>
<code> </code><code>assertnotnull(factory.getbean(</code><code>"aaa"</code><code>));</code>
<code> </code><code>bbb bbb = factory.getbean(</code><code>"bbb"</code><code>);</code>
<code> </code><code>assertequals(</code><code>"aaa"</code><code>, bbb.getaaa().getname());</code>
<code> </code><code>bbb = factory.getbean(</code><code>"bbb"</code><code>);</code>
<code> </code><code>ccc ccc = factory.getbean(</code><code>"ccc"</code><code>);</code>
<code> </code><code>assertequals(</code><code>"aaa1"</code><code>, ccc.getaaa1().getname());</code>
<code> </code><code>ccc = factory.getbean(</code><code>"ccc"</code><code>);</code>
<code> </code><code>}</code>
<code> </code><code>public</code> <code>void</code> <code>testinitcompareprototype() {</code>
<code> </code><code>cat cat = factory.getbean(</code><code>"cat1"</code><code>);</code>
<code> </code><code>cat cat1 = factory.getbean(</code><code>"cat1"</code><code>);</code>
<code> </code><code>assertequals(</code><code>false</code><code>, cat == cat1);</code>
<code> </code><code>public</code> <code>void</code> <code>testinitcompareprototype1() {</code>
<code> </code><code>user user = factory.getbean(</code><code>"user2"</code><code>);</code>
<code> </code><code>user user2 = factory.getbean(</code><code>"user2"</code><code>);</code>
<code> </code><code>assertequals(</code><code>false</code><code>, user == user2);</code>
<code> </code><code>assertequals(</code><code>false</code><code>, user.getcatmap() == user2.getcat());</code>
小結:确實,現在要脫離spring自己再實作一個容器,越來越不合适了,畢竟spring的使用者群在那裡,大家都已經熟悉适用的東西,不管是從學習成本各方面都不會選擇一個新東西。
ok,雖然是一個失敗的實踐,但是自己實作與看spring源碼的差别還是有的,就當是一次學習吧。當然,如果是在嵌入式系統或者受限制使用的環境中,隻想使用ioc,還是有用處的,畢竟 20k大小的容量還是相當誘人的。