Пример аннотации Spring AOP AspectJ

Пример аннотации Spring AOP + AspectJ

В этом руководстве мы покажем, как интегрировать аннотацию AspectJ с платформой Spring AOP. Проще говоря, Spring AOP + AspectJ позволяет легко перехватывать метод.

Общие аннотации AspectJ:

  1. @Before - Выполнить перед выполнением метода

  2. @After - Запускать после того, как метод вернул результат

  3. @AfterReturning - запускать после того, как метод вернул результат, также перехватить возвращенный результат.

  4. @AfterThrowing - запускается после того, как метод выдает исключение

  5. @Around - Выполните выполнение метода, объедините все три совета выше.

Note
Для Spring AOP без поддержки AspectJ прочтите этотbuild-in Spring AOP examples.

1. Структура каталогов

Смотрите структуру каталогов этого примера.

directory structure of this example

2. Зависимости проекта

Чтобы включить AspectJ, вам нужныaspectjrt.jar,aspectjweaver.jar иspring-aop.jar. См. Следующий файл Mavenpom.xml.

AspectJ supported since Spring 2.0
В этом примере используется Spring 3, но функции AspectJ поддерживаются начиная с Spring 2.0.

Файл: pom.xml



    
        3.0.5.RELEASE
    

    

        
            org.springframework
            spring-core
            ${spring.version}
        

        
            org.springframework
            spring-context
            ${spring.version}
        

        
        
            org.springframework
            spring-aop
            ${spring.version}
        

        
            org.aspectj
            aspectjrt
            1.6.11
        

        
            org.aspectj
            aspectjweaver
            1.6.11
        

    

3. Весенние бобы

Обычный бин, с несколькими методами, позже перехватывает его с помощью аннотации AspectJ.

package com.example.customer.bo;

public interface CustomerBo {

    void addCustomer();

    String addCustomerReturnValue();

    void addCustomerThrowException() throws Exception;

    void addCustomerAround(String name);
}
package com.example.customer.bo.impl;

import com.example.customer.bo.CustomerBo;

public class CustomerBoImpl implements CustomerBo {

    public void addCustomer(){
        System.out.println("addCustomer() is running ");
    }

    public String addCustomerReturnValue(){
        System.out.println("addCustomerReturnValue() is running ");
        return "abc";
    }

    public void addCustomerThrowException() throws Exception {
        System.out.println("addCustomerThrowException() is running ");
        throw new Exception("Generic Error");
    }

    public void addCustomerAround(String name){
        System.out.println("addCustomerAround() is running, args : " + name);
    }
}

4. Включить AspectJ

В файле конфигурации Spring поместите «<aop:aspectj-autoproxy />» и определите свой аспект (перехватчик) и обычный компонент.

Файл: Spring-Customer.xml



    

    

    
    

4. AspectJ @ Before

В приведенном ниже примере методlogBefore() будет выполнен до выполнения интерфейса customerBo, методаaddCustomer().

Note
AspectJ «pointcuts» используется для объявления метода, который будет перехватывать, и вы должны обратиться к этомуSpring AOP pointcuts guide для получения полного списка поддерживаемых выражений pointcuts.

Файл: LoggingAspect.java

package com.example.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class LoggingAspect {

    @Before("execution(* com.example.customer.bo.CustomerBo.addCustomer(..))")
    public void logBefore(JoinPoint joinPoint) {

        System.out.println("logBefore() is running!");
        System.out.println("hijacked : " + joinPoint.getSignature().getName());
        System.out.println("******");
    }

}

Запустить его

    CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
    customer.addCustomer();

Выход

logBefore() is running!
hijacked : addCustomer
******
addCustomer() is running

5. AspectJ @After

В приведенном ниже примере методlogAfter() будет выполнен после выполнения интерфейса customerBo, методаaddCustomer().

Файл: LoggingAspect.java

package com.example.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.After;

@Aspect
public class LoggingAspect {

    @After("execution(* com.example.customer.bo.CustomerBo.addCustomer(..))")
    public void logAfter(JoinPoint joinPoint) {

        System.out.println("logAfter() is running!");
        System.out.println("hijacked : " + joinPoint.getSignature().getName());
        System.out.println("******");

    }

}

Запустить его

    CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
    customer.addCustomer();

Выход

addCustomer() is running
logAfter() is running!
hijacked : addCustomer
******

6. AspectJ @AfterReturning

В приведенном ниже примере методlogAfterReturning() будет выполнен после выполнения интерфейса customerBo, методаaddCustomerReturnValue(). Кроме того, вы можете перехватить возвращаемое значение с помощью атрибута «returning».

Чтобы перехватить возвращаемое значение, значение «возвращаемого» атрибута (результата) должно совпадать с параметром метода (результат).

Файл: LoggingAspect.java

package com.example.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;

@Aspect
public class LoggingAspect {

   @AfterReturning(
      pointcut = "execution(* com.example.customer.bo.CustomerBo.addCustomerReturnValue(..))",
      returning= "result")
   public void logAfterReturning(JoinPoint joinPoint, Object result) {

    System.out.println("logAfterReturning() is running!");
    System.out.println("hijacked : " + joinPoint.getSignature().getName());
    System.out.println("Method returned value is : " + result);
    System.out.println("******");

   }

}

Запустить его

    CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
    customer.addCustomerReturnValue();

Выход

addCustomerReturnValue() is running
logAfterReturning() is running!
hijacked : addCustomerReturnValue
Method returned value is : abc
******

7. AspectJ @AfterReturning

В приведенном ниже примере методlogAfterThrowing() будет выполнен, если интерфейс customerBo, методaddCustomerThrowException() генерирует исключение.

Файл: LoggingAspect.java

package com.example.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;

@Aspect
public class LoggingAspect {

   @AfterThrowing(
      pointcut = "execution(* com.example.customer.bo.CustomerBo.addCustomerThrowException(..))",
      throwing= "error")
    public void logAfterThrowing(JoinPoint joinPoint, Throwable error) {

    System.out.println("logAfterThrowing() is running!");
    System.out.println("hijacked : " + joinPoint.getSignature().getName());
    System.out.println("Exception : " + error);
    System.out.println("******");

    }
}

Запустить его

    CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
    customer.addCustomerThrowException();

Выход

addCustomerThrowException() is running
logAfterThrowing() is running!
hijacked : addCustomerThrowException
Exception : java.lang.Exception: Generic Error
******
Exception in thread "main" java.lang.Exception: Generic Error
    //...

8. AspectJ @Around

В приведенном ниже примере методlogAround() будет выполняться перед интерфейсом customerBo, методомaddCustomerAround(), и вы должны определить «joinPoint.proceed();», чтобы контролировать, когда перехватчик должен вернуть управление объекту оригинальный методaddCustomerAround().

Файл: LoggingAspect.java

package com.example.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;

@Aspect
public class LoggingAspect {

   @Around("execution(* com.example.customer.bo.CustomerBo.addCustomerAround(..))")
   public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {

    System.out.println("logAround() is running!");
    System.out.println("hijacked method : " + joinPoint.getSignature().getName());
    System.out.println("hijacked arguments : " + Arrays.toString(joinPoint.getArgs()));

    System.out.println("Around before is running!");
    joinPoint.proceed(); //continue on the intercepted method
    System.out.println("Around after is running!");

    System.out.println("******");

   }

}

Запустить его

    CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
    customer.addCustomerAround("example");

Выход

logAround() is running!
hijacked method : addCustomerAround
hijacked arguments : [example]
Around before is running!
addCustomerAround() is running, args : example
Around after is running!
******

Заключение

Всегда рекомендуется применять аннотацию AsjectJ с наименьшей мощностью. Это довольно длинная статья об AspectJ весной. для дальнейших объяснений и примеров, пожалуйста, перейдите по ссылкам ниже.

Anti annotation or using JDK 1.4 ?
Не беспокойтесь, AspectJ также поддерживает конфигурацию XML, прочтите этотSpring AOP + AspectJ XML example.

Скачать исходный код

Скачать -Spring3-AOP-AspectJ-Example.zip (8 КБ)