вторник, 23 сентября 2008 г.

Simple Example for running apectj in standalone application

I'm use IDEA for running app, you can use any other.
First at all we need download aspectJ from their web site.

Application in my example run with on fly or wrapping real-time mode. For this you must run JVM with additional parameter:
-javaagent:aspectjweaver.jar
in IDEA what you need is just put aspectjweaver.jar in root of you application.

Also we need aop.xml aspectj configuration file. It placed in src/META-INF directroy.
Here is my aop.xml file body:

<aspectj>
<aspects>
<aspect name="ru.aspect.AspectJTest"/>
</aspects>
<weaver>
<include within="ru.*"/>
</weaver>
</aspectj>


weaver additional options such as debug and byte code dump you can see here

create aspect class:

package ru;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

@Aspect
public class AspectJTest {
@Around("execution(* *..*(..))")
public void around(ProceedingJoinPoint jp) throws Throwable {
jp.proceed();
}
}


in this example aspect will be invoked any time, when same method invoked.
i know 3 annotation for aspects method:
@Around
@Before
@After

if you use @Before or @Around in you method declaration you must use JoinPoint class parameter, for example:
@Before("execution(* *..*(..))")
public void before(JoinPoint jp) throws Throwable

aspecj has many different joinpoints, full list you can see in correspondent document page

that is all what we need for run this simple test.

If you want use annotation in you AOP application, first at all you need create correcponding interfaces:

package ru.aspect;

import org.jboss.aop.advice.Scope;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value = ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AspectTest {
}

You can setup different type of Target:
ElementType.METHOD - annotation for method
ElementType.CONSTRUCTOR - annotation for constructor
ElementType.PACKAGE - annotation for package
ElementType.PARAMETER - annotation for parameter in method
ElementType.FIELD - annotation for field in class

for policy RetentionPolicy.RUNTIME read corresponding documentation

Remember annotation not work for some static (need more data)

And for end some perfomance testing.
i'm use 3 situation:
1 run method without any aspect
2 run method with annotated aspect
3 run method with aspect (without annotation)

class for test:

package ru;
import ru.aspect.AspectTest;

public class TestAspect {
public void doItWithout(int i) {
double s = Math.acos(i);
}

@AspectTest
public void doItAnnotated(int i) {
double s = Math.acos(i);
}

public void doItAspect(int i) {
double s = Math.acos(i);
}
}

here test invoke

package ru;
import java.util.Date;
public class Test {
public Test() {
}
public static void main(String arg[]) {
//perfomance testing
//invoke method without aspect
long t1 = new Date().getTime();
for (int i = 0; i < 100000; i++) {
new TestAspect().doItWithout(i);
}
System.out.println("Invoke without aspect:"+(new Date().getTime()-t1));
//invoke method with annotated aspect
t1 = new Date().getTime();
for (int i = 0; i < 100000; i++) {
new TestAspect().doItAnnotated(i);
}
System.out.println("Invoke annotated aspect method:"+(new Date().getTime()-t1));
//invoke method with aspect but not annotated
t1 = new Date().getTime();
for (int i = 0; i < 100000; i++) {
new TestAspect().doItAspect(i);
}
System.out.println("Invoke aspect method:"+(new Date().getTime()-t1));
}
}

performance result:
Invoke without aspect:31
Invoke annotated aspect method:94
Invoke aspect method:46


If you has any question just mail me: mailtosmyk@gmail.com

Комментариев нет: