/blog/*

Implementasi Spring AOP dengan AspectJ

Pada tulisan sebelumnya telah dibahas bagaimana mengimplementasikan konsep AOP pada Spring namun masih menggunakan XML config. Jika kita ingin mengimplementasikan konsep AOP dengan annotation config, Spring membutuhkan bantuan library tambahan seperti aspectj.

<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.5</version>
    </dependency>
    ...
</dependencies>

Aspect

Kita tahu bahwa elemen utama dari konsep AOP adalah advice, dan untuk mendefinisikan advice menggunakan library aspectj kita cukup membuat class aspect dan diberi annotation @Aspect. Aspect dalam konteks disini sebenarnya hanya kombinasi dari advice + pointcut. Berikut contoh programnya dan kita akan bahas detailnya:

@Aspect
@Component
@Order(1)
public class LoggingAspect {

    @Pointcut("execution(* com.hiwijaya.aop.BankAccount.*(..))")
    public void loggingPointcut(){}

    @Before("loggingPointcut()")
    public void beforeAdvice(JoinPoint point) {

        ...

    }

    @AfterReturning(pointcut = "loggingPointcut()", returning="returnValue")
    public void afterAdvice(JoinPoint point, Object returnValue){

        ...

    }

}
  • Annotation @Aspect digunakan untuk memberitahu Spring bahwa class tersebut merupakan Aspect yang nantinya akan diproses untuk menghasilkan object Proxy.
  • Class yang diberi anotasi @Component proses inisialisasi dan pembuatan object nya akan dihandle sepenuhnya oleh Spring. Kita akan bahas prinsip Inversion of Control secara mendalam di tulisan lain.
  • Jika terdapat kasus dimana memiliki beberapa advice, manakah yang akan dieksekusi terlebih dahulu? Untuk menentukan urutan tersebut, kita bisa menggunakan annotation @Order() dimana parameter pada annotation tersebut menentukan urutan eksekusi advice. Atau cara lainnya adalah dengan mengimplementasikan interface Ordered yang memiliki satu method getOrder().
  • Dalam class aspect, selain untuk mendefinisikan advice kita juga mendefinisikan pointcut disini. Untuk mendifinisikan target mana saja yang akan disisipkan advice, Spring mendukung penggunaan expression aspectj yang disebut pointcut designators(PCD).
  • @Before() digunakan untuk menandai bahwa advice ini akan dieksekusi sebelum target dijalankan.
  • @AfterReturning() menandakan bahwa advice ini akan dieksekusi setelah target. Selain itu jika terdapat return value, kita bisa passing ke advice.

Untuk mendukung around advice, aspectj memiliki annotation @Around() yang bisa kita gunakan pada class aspect.

@Aspect
@Component
public class MonitoringAspect {

    // pointcut here

    @Around("monitoringPointcut()")
    public Object aroundAdvice(ProceedingJoinPoint point) throws Throwable {
        ...
    }

}

Config

Terakhir adalah mendeklarasikan class Config yang ditandai dengan anotasi @Configuration.

@Configuration
@EnableAspectJAutoProxy     // or <aop:aspectj-autoproxy/> on xml config
@ComponentScan("com.hiwijaya.aop.aspect")
public class AnnotationConfig {

    @Bean("account")
    public BankAccount getAccount(){
        return new BankAccount("Happy Indra Wijaya", "1234567890");
    }

}

Dengan mendeklarasikan annotation @EnableAspectJAutoProxy, Spring akan membuatkan object Proxy berdasarkan class-classs aspect yang sudah kita buat.

Untuk kode program lengkap dari contoh diatas dapat diakses disini.

Ref: