Spring.Net對方法的注入(學習筆記三)
Spring除了對屬性、事件注入外,還可以通過配置實現對方法的注入。這一節說說Spring.Net框架對方法的注入方式。
Spring對方法的注入有兩種方式,本節要說明的就是它的兩種注入方式:
1、查詢方法注入(lookup method Injection)
2、替換任意方法注入
先介紹開發環境及Spring版本: VS2008 SP1。Spring版本:1.3.0。
1.查詢方法注入。
Spring.Net可以對動態的對目標對象的抽象方法或者虛方法進行覆蓋,并且可以在容器類查找已命名的對象,查詢方法注入就利用了這一功能。被查詢的對象一般應該是非Singleton的,但是也可以是Singleton的。Spring.NET使用System.Reflecttion.Emit命名空間中的類型在運行時動態生成某個類的子類并覆蓋其方法,以實現查詢方法注入。被注入的方法應該是抽象無參數的或者虛方法,并且方法的可見性應該在Private以上(因為抽象方法或者虛方法設置為private就沒有意義)。
配置方式如下:
代碼
1 <objects xmlns="http://www.springframework.net" xmlns:aop="http://www.springframework.net/aop">
2 <object id="parent" type="lookUpMethod.Parent,lookUpMethod" singleton="false">
3 <lookup-method name="CreateInstance" object="children" />
4
5 </object>
6
7 <object id="children" type="lookUpMethod.Children,lookUpMethod">
8
9 </object>
10 </objects>
類代碼:
代碼
1 public abstract class Parent
2 {
3 //public abstract Children CreateInstance();
4
5 public virtual Children CreateInstance()
6 {
7 return null;
8 }
9 }
10 public class Children
11 {
12 public void TestMethod()
13 {
14 Console.WriteLine("Chileren method" );
15
16 }
17 }
使用方式:
代碼
1 static void Main(string[] args)
2 {
3 IApplicationContext context = ContextRegistry.GetContext();
4
5 Parent parent = (Parent)context.GetObject("parent");
6 Console.WriteLine(parent.CreateInstance().ToString());
7 parent.CreateInstance().TestMethod();
8 Console.ReadLine();
9
10 }
結果如下圖:

由運行的結果我們可以看出:調用parent的抽象方法CreateInstance時,實際上返回了children的類型。
如果我們將抽象方法CreateInstance增加一個string類型的參數,將方法的簽名改成如下方式:
public abstract Children CreateInstance(string str);
使用方式改成:
Console.WriteLine(parent.CreateInstance("aa").ToString());
parent.CreateInstance("aa").TestMethod("str");
則運行出現如下圖示異常:

parent中抽象方法、虛方法運行結果是完全一樣的。大家有興趣可以試試。
由以上用法可以總結出以下結論:
被注入的方法不能帶參數。
2、替換方法注入
這是一種用的比較少的注入方式。在Spring的配置中,通過replaced-method在需要替換類中指定需要被替換的方法,以及被哪個類替換。替換類應該實現Spring.Objects.Factory.Support中的IMethodReplacer接口。IMethodReplacer接口只有一個object Implement(object target, MethodInfo method, object[] arguments)方法。當我們調用被替換類中相應方法時,會執行Implement方法。當然,我們可以中Implement中,通過參數信息獲取到相應的部分信息。
配置如下:
代碼
1 <objects xmlns="http://www.springframework.net" xmlns:aop="http://www.springframework.net/aop">
2 <object id="parent" type="ReplaceMethod.Parent,ReplaceMethod">
3 <replaced-method name="ParentMethod" replacer="children">
4 <!--<arg-type match=""/>-->
5 </replaced-method>
6 <replaced-method name="ParentMethod" replacer="children">
7 <arg-type match="String"/>
8 </replaced-method>
9 </object>
10 <object id="children" type="ReplaceMethod.Children,ReplaceMethod">
11
12 </object>
13 </objects>
被替換類的代碼如下:
代碼
1 public class Parent
2 {
3 public virtual void ParentMethod()
4 {
5 Console.WriteLine("parent methods");
6 }
7
8 public virtual void ParentMethod(string str)
9 {
10 Console.WriteLine("method with parament:" + str);
11 }
12 }
代碼
1 public class Children : IMethodReplacer
2 {
3 public object Implement(object target, MethodInfo method, object[] arguments)
4 {
5 Console.WriteLine("target type is:{0}",target.ToString());
6 Console.WriteLine("method name is :{0}",method.Name);
7 if (arguments.Length > 0)
8 {
9 Console.WriteLine("the first element in artmennts is :{0}", arguments[0].ToString());
10 }
11 return new object();
12 }
13
14 }
使用方式:
代碼
1 static void Main(string[] args)
2 {
3 IApplicationContext context = ContextRegistry.GetContext();
4
5 Parent parent = (Parent)context.GetObject("parent");
6 parent.ParentMethod();
7
8 parent.ParentMethod("test str");
9 Console.ReadLine();
10
11 }

由運行結果我們可以得知:上面兩行是調用沒有參數的函數調用的結果,下面三行是帶有參數的函數調用的結果。
結論:
1、在替換方法注入中,在被替換類中的具有重載的方法,通過replaced-method節點中的arg-type指定的。
2、在被替換類中,需要被替換的方法需要是虛方法或者抽象方法(否則異常會通查詢方法中不設置為虛方法或抽象方法的異常相同).
代碼下載:Spring中的方法注入
參考文檔:Spring.Net框架參考
浙公網安備 33010602011771號