DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world
An Excerpt From "Managing Cross-Cutting Concerns Using Mixin Composition And AOP" From Jonas Boner
// A little scala script with the AOP part of his post at
// http://java.dzone.com/articles/real-world-scala-managing-cros
// 1 - add aspectjweaver.jar to your classpath
// 2 - paste this code to jbtest2.scala
// 3 - scalac -target:jvm-1.5 -d classes jbtest2.scala
// 4 - scala -classpath classes;%classpath% jbtest2
// 5 - have some fun ! Thanks Jonas
// jbtest2.scala
import org.aspectj.weaver.tools.PointcutParser
import org.aspectj.weaver.tools.PointcutExpression
import java.lang.annotation.Annotation
import java.lang.reflect.InvocationHandler
import java.lang.reflect.Proxy
import java.lang.reflect.Method
object jbtest2 {
def main(args: Array[String]) = {
println("hello ")
var foo = ManagedComponentFactory.createComponent[Foo](
classOf[Foo],
new ManagedComponentProxy(new FooImpl) with LoggingInterceptor with TransactionInterceptor)
foo.foo("foo")
foo.bar("bar")
println("bye ")
}
}
case class Invocation(val method: Method, val args: Array[AnyRef], val target: AnyRef) {
def invoke: AnyRef = method.invoke(target, args:_*)
override def toString: String = "Invocation [method: " + method.getName + ", args: " + args + ", target: " + target + "]"
override def hashCode(): Int = { 3 }
override def equals(that: Any): Boolean = { true }
}
trait Interceptor {
protected val parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution()
protected def matches(pointcut: PointcutExpression, invocation: Invocation): Boolean = {
pointcut.matchesMethodExecution(invocation.method).alwaysMatches ||
invocation.target.getClass.getDeclaredMethods.exists(pointcut.matchesMethodExecution(_).alwaysMatches) ||
false
}
protected def matches(annotationClass: Class[T] forSome {type T <: Annotation}, invocation: Invocation): Boolean = {
invocation.method.isAnnotationPresent(annotationClass) ||
invocation.target.getClass.isAnnotationPresent(annotationClass) ||
false
}
def invoke(invocation: Invocation): AnyRef
}
object ManagedComponentFactory {
def createComponent[T](intf: Class[T] forSome {type T}, proxy: ManagedComponentProxy): T =
Proxy.newProxyInstance(
proxy.target.getClass.getClassLoader,
Array(intf),
proxy).asInstanceOf[T]
}
class ManagedComponentProxy(val target: AnyRef) extends InvocationHandler {
def invoke(proxy: AnyRef, m: Method, args: Array[AnyRef]): AnyRef = invoke(Invocation(m, args, target))
def invoke(invocation: Invocation): AnyRef = invocation.invoke
}
trait Foo {
@Deprecated
def foo(msg: String)
def bar(msg: String)
}
class FooImpl extends Foo {
val bar: Bar = new BarImpl
def foo(msg: String) = println("msg: " + msg)
def bar(msg: String) = bar.bar(msg)
}
trait Bar {
def bar(msg: String)
}
class BarImpl extends Bar {
def bar(msg: String) = println("msg: " + msg)
}
trait LoggingInterceptor extends Interceptor {
val loggingPointcut = parser.parsePointcutExpression("execution(* *.foo(..))")
abstract override def invoke(invocation: Invocation): AnyRef =
if (matches(loggingPointcut , invocation)) {
println("=====> Enter: " + invocation.method.getName + " @ " + invocation.target.getClass.getName)
val result = super.invoke(invocation)
println("=====> Exit: " + invocation.method.getName + " @ " + invocation.target.getClass.getName)
result
} else super.invoke(invocation)
}
trait TransactionInterceptor extends Interceptor {
// using Deprecated annotation instead of javax.ejb.TransactionAttribute just to have less jars to set up
val matchingDeprecatedAnnotation = classOf[java.lang.Deprecated]
abstract override def invoke(invocation: Invocation): AnyRef =
if (matches(matchingDeprecatedAnnotation, invocation)) {
println("=====> interceptor begin")
try {
// val result = super.doStuff
val result = super.invoke(invocation)
println("=====> interceptor commit")
result
} catch {
case e: Exception =>
println("=====> interceptor rollback since we got an exception")
}
} else super.invoke(invocation)
}





