C Aop簡單掃盲及ORM實體類屬性攔截示例

2021-09-23 12:46:00 字數 2795 閱讀 1678

本人只是想攔截實體類的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...