本人只是想攔截實體類的set的方法,然後在set之前,呼叫一下其它方法,把值賦給另乙個物件。
而我做的都是在實體類的基類裡處理:
比如:public class ormbase
讓所有繼承這個基類的實體類都具有orm操作功能,再加上乙個小小特殊的要求處理,屬性set時,需要對另一物件賦值。
如果說,我這樣實現:在ormbase中可以提供方法,讓所有的子類的屬性都這樣操作:
public class users:ormbase
}
不過每個實體都這樣寫,雖然是啥沒問題,不過能簡化的還是簡化。
在能追求簡潔的世界裡,當然更喜歡簡潔的寫法如:
因此,直接在基類裡直接攔截子類set方法,在裡面直接呼叫setxx就搞定了,如何實現呢?又花了一天的時間查資料研究學習並實現。
為此,要攔截,就得折騰aop:
傳統的aop使用realproxy,使用非常簡單,但是被忽悠的非常複雜,下面:
1:在要攔截的類頭上加個屬性標識,同時繼承自contextboundobject:
[aopattribute]
public class ormbase:contextboundobject
ok,在基類裡加乙個,這樣所有子類也算被附加了,加上乙個標識,就可以被攔截了,那這個aopattribute屬性是啥?看下面
2:aopattribute繼承**屬性標識類,用來掛在要攔截的類的頭上:
class aopattribute : proxyattribute
}
看,裡面就兩行,非常簡單,中間呼叫了繼承realproxy的aopproxy類,aopproxy是什麼,怎麼出來的?看下面
3:aopproxy類,就是攔截的訊息處理,先上個簡單版,免的大夥看不懂:
class aopproxy : realproxy
public override imessage invoke(imessage msg)
}
ok,簡單吧,就這麼兩個類,就可以實現攔截了,不過重點就是這裡攔截之後的**,稍為複雜點,一般照抄就行了,攔截的**如下:
if (msg is iconstructioncallmessage) // 如果是建構函式,按原來的方式返回即可。
iconstructioncallmessage constructcallmsg = msg as iconstructioncallmessage;
iconstructionreturnmessage constructionreturnmessage = this.initializeserverobject((iconstructioncallmessage)msg);
realproxy.setstubdata(this, constructionreturnmessage.returnvalue);
return constructionreturnmessage;
else if (msg is imethodcallmessage) //如果是方法呼叫(屬性也是方法呼叫的一種)
imethodcallmessage callmsg = msg as imethodcallmessage;
object args = callmsg.args;
imessage message;
tryif (callmsg.methodname.startswith("set_") && args.length == 1)
//這裡檢測到是set方法,然後應怎麼呼叫物件的其它方法呢?
message = new returnmessage(o, args, args.length, callmsg.logicalcallcontext, callmsg);
catch (exception e)
message = new returnmessage(e, callmsg);
return message;
return msg;
為了呼叫原始物件的其它方法,我花了近一天的時間查資料,可惜網路上並沒有相應的資訊,多數的人應用,都是引向乙個其它方法(乙個不需要呼叫原始物件的方法)
於是,我按傳統方式,想盡辦法的想獲取到原始物件,再呼叫,經過九九八十一招,還是失敗了。
(一開始是想:通過反射從型別再建立乙個實體這種不靠譜的嘗試: 造成死迴圈,每次new攔截,在攔截裡又new)
中間省一大堆......痛苦的經歷和嘗試.......
只要用心想,方法總有的,最終還是被我發現了:
1:獲取要呼叫的方法:
在建構函式中,根據傳進來的servertype,獲取到setxx的方法methodinfo:
method = servertype.getmethod("setxx", bindingflags.nonpublic | bindingflags.instance);
2:在攔截方法中呼叫:
if (callmsg.methodname.startswith("set_") && args.length == 1)
過程很複雜,嘗試過n百種方式,結果很簡單,分享很重要!
為此,解決了orm對子類的屬性攔截,並實現了在屬性賦值時呼叫例項其它方法。
C Aop簡單掃盲及ORM實體類屬性攔截示例
本人只是想攔截實體類的set的方法,然後在set之前,呼叫一下其它方法,把值賦給另乙個物件。而我做的都是在實體類的基類裡處理 比如 public class ormbase 讓所有繼承這個基類的實體類都具有orm操作功能,再加上乙個小小特殊的要求處理,屬性set時,需要對另一物件賦值。如果說,我這樣...
C Aop簡單掃盲及ORM實體類屬性攔截示例
本人只是想攔截實體類的set的方法,然後在set之前,呼叫一下其它方法,把值賦給另乙個物件。而我做的都是在實體類的基類裡處理 比如 public class ormbase 讓所有繼承這個基類的實體類都具有orm操作功能,再加上乙個小小特殊的要求處理,屬性set時,需要對另一物件賦值。如果說,我這樣...
實現ORM模型一鍵生成實體類
使用方法 配置resources generactor.properties檔案 在com.dgy.main中執行main方法 主要的方法 取得mysql資料庫的表的字段資訊 查詢乙個表的所有列資訊 param tablename return public static mapgetcloumin...