Dalam artikel terdahulu saya telah memberikan beberapa contoh penggunaan metodologi AOP dengan menggunakan beberapa cara, salah satunya dengan menggunakan spring classic aop. Dengan menggunakan spring classic aop kita harus membuat proxy dengan mendefinisikan secara eksplisit kebutuhan akan kelas kelas untuk membuat proxy tersebut. Nah, dengan Spring AspectJ kita dapat dengan mudah mendefinisikan agar melakukan scanning terhadap kelas-kelas yang dianggap sebagai sebuah aspek dan membuatkan proxy untuk masing-masing kelas tersebut.
Sebuah kelas aspek dapat ditandai dengan sebuah anotasi @Aspect. Sebuah kelas aspek juga dapat ditandai dengan melakukan injeksi secara langsung didalam sebuah container. Untuk mengimplementasikan automatic proxy maka kita dapat mendefinisikan sebuah element xml seperti berikut :
<aop:aspectj-autoproxy/>
Berdasarkan contoh sebelumnya mari kita langsung saja ke listing berikut :
Kita buat sebuah interface Kalkulator :
public interface Kalkulator {
public double kali(double x, double y);
public double bagi(double x, double y);
}
Kemudian lakukan implementasi dari interface tersebut :
public class KalkulatorImpl implements Kalkulator {
public double bagi(double x, double y) {
if (y == 0) {
throw new IllegalArgumentException("Pembagi tidak boleh 0");
}
double hasil = x / y;
return hasil;
}
public double kali(double x, double y) {
double hasil = x * y;
return hasil;
}
}
Setelah itu kita buatkan sebuah kelas aspek untuk mengatur log yang terjadi :
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
*
* @author kris
*/
@Aspect
public class KalkulatorAspect {
private Log log = LogFactory.getLog(this.getClass());
@Before("execution(* *.*(..))")
public void runBefore(JoinPoint joinPoint) {
log.info("Method " + joinPoint.getSignature().getName() + " () telah dijalankan");
}
@AfterReturning(pointcut = "execution(* *.*(..))", returning = "result")
public void runAfterReturning(JoinPoint joinPoint, Object result) {
log.info("Method " + joinPoint.getSignature().getName() + " () telah dijalankan dengan hasil : " + result);
}
@AfterThrowing(pointcut = "execution(* *.*(..))", throwing = "e")
public void runAfterThrowing(JoinPoint joinPoint, Throwable e) {
log.info("Terjadi error " + e + " didalam method " + joinPoint.getSignature().getName());
}
}
Jika melihat kode diatas maka ada beberapa advice yang digunakan. @Before,@AfterReturning,@AfterThrowing. Seperti dalam artikel yang lalu, advice Before akan dijalankan sebelum target method dieksekusi, advice AfterReturning akan dijalankan setelah target method dieksekusi. Advice AfterThrowing akan dieksekusi jika terjadi kesalahan dalam target method tersebut. Mungkin kita juga menemukan beberapa istilah baru didalam listing diatas, antara lain adalah JoinPoint.
JoinPoint dapat diartikan sebagai sebuah execution point yang tepat didalam sebuah pointcut. Lalu, apa itu poincut ? Poincut dapat diartikan sebagai sebuah penunjuk untuk mengarahkan advice tertentu kedalam execution points agar menujuk pada target kelas dan target method tertentu. Jadi poincut dapat berupa wildcard(*) sebagai penunjuk modifier, return type, paket dan nama kelas tertentu. Seperti halnya wildcard yang lain yang berarti apa saja, hal ini juga berlaku pada poincut yang biasa disebut juga denga reguler expression.
Kemudian kita perlu mendaftarkan kelas-kelas yang terlibat didalam container :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<aop:aspectj-autoproxy/>
<bean id="kalkulator" class="org.kris.aspectj.basic.KalkulatorImpl"/>
<bean class="org.kris.aspectj.basic.KalkulatorAspect"/>
</beans>
Setelah itu kita dapat membuatkan kelas utamanya sebagai berikut :
public class MainClass {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("org/kris/aspectj/basic/container.xml");
Kalkulator kalkulator = (Kalkulator) context.getBean("kalkulator");
kalkulator.kali(2, 2);
kalkulator.bagi(2, 0);
}
}
Hasilnya :
….
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@39b8d6f7: defining beans [org.kris.aspectj.basic.KalkulatorAspect#0,kalkulator,org.springframework.aop.config.internalAutoProxyCreator]; root of factory hierarchy
Nov 27, 2009 12:18:58 PM org.kris.aspectj.basic.KalkulatorAspect runBefore
INFO: Method kali () telah dijalankan
Nov 27, 2009 12:18:58 PM org.kris.aspectj.basic.KalkulatorAspect runAfterReturning
INFO: Method kali () telah dijalankan dengan hasil : 4.0
Nov 27, 2009 12:18:58 PM org.kris.aspectj.basic.KalkulatorAspect runBefore
INFO: Method bagi () telah dijalankan
Nov 27, 2009 12:18:58 PM org.kris.aspectj.basic.KalkulatorAspect runAfterThrowing
INFO: Terjadi error java.lang.IllegalArgumentException: Pembagi tidak boleh 0 didalam method bagi
Exception in thread "main" java.lang.IllegalArgumentException: Pembagi tidak boleh 0
at org.kris.aspectj.basic.KalkulatorImpl.bagi(KalkulatorImpl.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
….
Dari hasil diatas kita dapat melihat urutan advice yang akan dijalankan dan result yang dihasilkan. Pada artikel selanjutnya saya akan mengupas lebih jauh penggunaan aspectj didalam spring. Ditunggu ya…….
Pokoke Muantep!!!!!!!!!!!!!!
Posted by mudzakkirtoha | February 25, 2010, 6:54 amwahh thx bro.. saya lebih mengerti sekarang…
Posted by ManiakJava | July 31, 2011, 2:18 pm