Пример Spring AOP - Pointcut, Advisor

Пример Spring AOP - Pointcut, Advisor

В последнемSpring AOP advice examples все методы класса перехватываются автоматически. Но в большинстве случаев вам может понадобиться способ перехвата только одного или двух методов, для этого и нужен «Pointcut». Это позволяет вам перехватить метод по имени метода. Кроме того, «Pointcut» должен быть связан с «Advisor».

В Spring AOP есть три очень технических термина -Advices, Pointcut , Advisor, выражаясь неофициально ...

  • Совет. Укажите действие, которое необходимо выполнить до или после выполнения метода.

  • Pointcut - Укажите, какой метод должен быть перехвачен, по имени метода или шаблону регулярного выражения.

  • Советник - сгруппируйте «Советы» и «Pointcut» в единое целое и передайте его объекту прокси-фабрики.

Просмотрите последнийSpring AOP advice examples еще раз.

Файл: CustomerService.java

package com.example.customer.services;

public class CustomerService
{
    private String name;
    private String url;

    public void setName(String name) {
        this.name = name;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void printName(){
        System.out.println("Customer name : " + this.name);
    }

    public void printURL(){
        System.out.println("Customer website : " + this.url);
    }

    public void printThrowException(){
        throw new IllegalArgumentException();
    }

}

Файл: Spring-Customer.xml



    
        
        
    

    

    

        

        
            
                hijackAroundMethodBeanAdvice
            
        
    

Файл: HijackAroundMethod.java

package com.example.aop;

import java.util.Arrays;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class HijackAroundMethod implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {

        System.out.println("Method name : "
                + methodInvocation.getMethod().getName());
        System.out.println("Method arguments : "
                + Arrays.toString(methodInvocation.getArguments()));

        System.out.println("HijackAroundMethod : Before method hijacked!");

        try {
            Object result = methodInvocation.proceed();
            System.out.println("HijackAroundMethod : Before after hijacked!");

            return result;

        } catch (IllegalArgumentException e) {

            System.out.println("HijackAroundMethod : Throw exception hijacked!");
            throw e;
        }
    }
}

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

package com.example.common;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.example.customer.services.CustomerService;

public class App {
    public static void main(String[] args) {
        ApplicationContext appContext = new ClassPathXmlApplicationContext(
                new String[] { "Spring-Customer.xml" });

        CustomerService cust = (CustomerService) appContext
                .getBean("customerServiceProxy");

        System.out.println("*************************");
        cust.printName();
        System.out.println("*************************");
        cust.printURL();
        System.out.println("*************************");
        try {
            cust.printThrowException();
        } catch (Exception e) {
        }
    }
}

Выход

*************************
Method name : printName
Method arguments : []
HijackAroundMethod : Before method hijacked!
Customer name : Yong Mook Kim
HijackAroundMethod : Before after hijacked!
*************************
Method name : printURL
Method arguments : []
HijackAroundMethod : Before method hijacked!
Customer website : http://www.example.com
HijackAroundMethod : Before after hijacked!
*************************
Method name : printThrowException
Method arguments : []
HijackAroundMethod : Before method hijacked!
HijackAroundMethod : Throw exception hijacked!

Все методы класса обслуживания клиентов перехвачены. Позже мы покажем вам, как использовать «pointcuts» для перехвата только методаprintName().

Пример Pointcuts

Вы можете сопоставить метод двумя способами:

  1. Название совпадения

  2. Регулярный репрессивный матч

1. Pointcuts - пример соответствия имени

Перехватите метод printName () с помощью «pointcut» и «advisor». Создайте bean-компонент pointcutNameMatchMethodPointcut и поместите имя метода, который вы хотите перехватить, в значение свойства «mappedName».

    
        
    

Создайте bean-компонент AdvisorDefaultPointcutAdvisor и свяжите с ним advice и pointcut.

    
        
        
    

Замените «interceptorNames» прокси на «customerAdvisor» (это был «hijackAroundMethodBeanAdvice»).

    

        

        
            
                customerAdvisor
            
        
    

Полный файл конфигурации бина



    
        
        
    

    

    

        

        
            
                customerAdvisor
            
        
    

    
        
    

    
        
        
    

Запустите это снова, вывод

*************************
Method name : printName
Method arguments : []
HijackAroundMethod : Before method hijacked!
Customer name : Yong Mook Kim
HijackAroundMethod : Before after hijacked!
*************************
Customer website : http://www.example.com
*************************

Теперь вы только перехватываете метод printName ().

PointcutAdvisor
Spring поставляется с классомPointcutAdvisor, чтобы сохранить вашу работу по объявлению советника и pointcut в разных bean-компонентах, вы можете использоватьNameMatchMethodPointcutAdvisor, чтобы объединить оба компонента в один bean-компонент.

    

        
        

    

2. Pointcut - Пример регулярного выражения

Вы также можете сопоставить имя метода с помощью регулярного выражения pointcut -RegexpMethodPointcutAdvisor.

    
        
            
                .*URL.*
            
        

        
    

Теперь он перехватывает метод, который содержит слова «URL» в имени метода. На практике вы можете использовать его для управления уровнем DAO, где вы можете объявить «.*DAO. *», чтобы перехватить все ваши классы DAO для поддержки транзакции.

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