Aspect-Oriented Programming framework for Go
BSD-3-CLAUSE License
AspectGo is an AOP framework for Go. You can write an aspect in a simple Go-compatible grammar.
I'm hoping to propose merging AspectGo to the upstream of golang.org/x/exp
if possible, but no concret plan yet.
Recipe:
The interface is not fixed yet. Your suggestion and PR are welcome.
$ go install github.com/AkihiroSuda/aspectgo/cmd/aspectgo
$ go build github.com/AkihiroSuda/aspectgo/example/hello && ./hello
hello
$ aspectgo \
-w /tmp/wovengopath \ # output gopath
-t github.com/AkihiroSuda/aspectgo/example/hello \ # target package
example/hello/main_aspect.go # aspect file
$ GOPATH=/tmp/wovengopath go build github.com/AkihiroSuda/aspectgo/example/hello && ./hello
BEFORE hello
hello
AFTER hello
The aspect is located on example/hello/main_aspect.go:
package main
import (
"fmt"
"regexp"
asp "github.com/AkihiroSuda/aspectgo/aspect"
)
// ExampleAspect implements interface asp.Aspect
type ExampleAspect struct {
}
// Executed on compilation-time
func (a *ExampleAspect) Pointcut() asp.Pointcut {
pkg := regexp.QuoteMeta("github.com/AkihiroSuda/aspectgo/example/hello")
s := pkg + ".*"
return asp.NewCallPointcutFromRegexp(s)
}
// Executed ONLY on runtime
func (a *ExampleAspect) Advice(ctx asp.Context) []interface{} {
args := ctx.Args()
fmt.Println("BEFORE hello")
res := ctx.Call(args)
fmt.Println("AFTER hello")
return res
}
The target is example/hello/main.go:
package main
import (
"fmt"
)
func sayHello(s string) {
fmt.Println("hello " + s)
}
func main() {
sayHello("world")
}
You can also execute other examples as follows:
$ go test -v github.com/AkihiroSuda/aspectgo/example
If the output is hard to read, please add the -parallel 1
flag to go test
.
/tmp/wovengopath
before running aspectgo
every time.aspectgo
for faster compilation.main
and init
) and method name can be a pointcut*S
, *T
implements I
, and there is a call to I.Foo()
in the target package. You can make a pointcut for I.Foo()
, but you can't make a pointcut for *S
nor *T
.