You signed in with another tab or window.Reload to refresh your session.You signed out in another tab or window.Reload to refresh your session.You switched accounts on another tab or window.Reload to refresh your session.Dismiss alert
current version is in alpha, welcome to submit your ideas (api is not stable current version)
Basic Usage
define struct
typeAuthstruct {}func (p*Auth)Login(userName,passwordstring)bool {ifuserName=="zeal"&&password=="gogap" {returntrue}returnfalse}// use join point to get Args from real methodfunc (p*Auth)Before(jp aop.JoinPointer) {username:=""jp.Args().MapTo(func(u,pstring) {username=u})fmt.Printf("Before Login: %s\n",username)}// the args is same as Loginfunc (p*Auth)After(username,passwordstring) {fmt.Printf("After Login: %s %s\n",username,password)}// use join point to around the real func of loginfunc (p*Auth)Around(pjp aop.ProceedingJoinPointer) {fmt.Println("@Begin Around")ret:=pjp.Proceed("fakeName","fakePassword")ret.MapTo(func(loginResultbool) {fmt.Println("@Proceed Result is",loginResult)})fmt.Println("@End Around")}
In this case, we want callBefore() func beforeLogin(), andAfter() func afterLogin()
So, if we have more funcs to call before and after, it will pollution the real logic funcLogin(), we want a proxy help us to invokeBefore() andAfter() automatic.
$> go run main.goBefore Login: zealAfter Login: zeal gogapLogin result:true
Advance
Pointcut expression
every condition expression is regex expression
pointcut:=aop.NewPointcut("pointcut_1")// will trigger the advice while call loginpointcut.Execution(`Login()`)// will trigger the advice will call any funcpointcut.Execution(`.*?`)// will not trigger the advice will call any funcpointcut.NotExecution(`Login()`)
other conditions:
WithIn
NotWithIn
Bean
NotBean
// will trigger the advie while we call Login// and in bean named authpointcut.Execution(`Login()`).Bean(`auth`)// will trigger the advie while we call Login// and in bean named auth and sysAuthpointcut.Execution(`Login()`).Bean(`auth`).Bean(`sysAuth`)// will trigger the advie while we call Login// and in bean named auth not sysAuthpointcut.Execution(`Login()`).Bean(`auth`).NotBean(`sysAuth`)// will trigger the advie while we call Login// and the call stacktrace should contain example/aop/mainpointcut.Execution(`Login()`).WithIn(`example/aop/main`)
typeFoostruct {}// @AfterReturning, the method could have args of aop.Result,// it will get the result from real func return valuesfunc (p*Foo)Bar(result aop.Result) {result.MapTo(func(vbool) {fmt.Println("Bar Bar Bar .... Result is:",v)})}
Before Login: zealBar Bar Bar .... Result is:trueAfter Login: zeal gogapLogin result:true
Turn on trace for debug
err:=aop.StartTrace()....// use proxy to call your funcst,err:=aop.StopTrace()for_,item:=ranget.Items() {fmt.Println(item.ID,item.InvokeID,item.BeanRefID,item.Pointcut,item.Method)}
$> go run main.gogo run main.go==========Func Type Assertion==========Before Login: zeal@Begin Around@Login fakeName fakePassword@Proceed Result isfalse@End AroundAfter Login: zeal gogapLogin result:false================Invoke=================Before Login: zeal@Begin Around@Login fakeName fakePassword@Proceed Result isfalse@End AroundAfter Login: zeal errorpasswordLogin result:false1 aqpk3jjhssa5ul6pt0h0 auth main.(Auth).Login Before2 aqpk3jjhssa5ul6pt0h0 auth main.(Auth).Login Around3 aqpk3jjhssa5ul6pt0h0 auth main.(Auth).Login*Login4 aqpk3jjhssa5ul6pt0h0 foo main.(Auth).Login Bar5 aqpk3jjhssa5ul6pt0h0 auth main.(Auth).Login After6 aqpk3jjhssa5ul6pt0hg auth main.(Auth).Login Before7 aqpk3jjhssa5ul6pt0hg auth main.(Auth).Login Around8 aqpk3jjhssa5ul6pt0hg auth main.(Auth).Login*Login9 aqpk3jjhssa5ul6pt0hg foo main.(Auth).Login Bar10 aqpk3jjhssa5ul6pt0hg auth main.(Auth).Login After