Spring

Spring - AOP - Pointcut , Adviso

2020-01-18  本文已影响0人  HRocky

原文地址:https://mkyong.com/spring/spring-aop-example-pointcut-advisor/

Spring - AOP - Advice中,一个类的所有方法都会被自动拦截。但是在大多数情况下,您可能需要一种方式来仅拦截一种或两种方法,这就是“切入点”的目的。它允许您通过方法名称来拦截方法。此外,“切入点”必须与“Advisor”相关联。

在Spring AOP中,提供了三个非常技术性的术语–Advice,Pointcut,Advisor,以非正式的方式进行介绍...

文件:CustomerService.java

package com.mkyong.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

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <bean id="customerService" class="com.mkyong.customer.services.CustomerService">
        <property name="name" value="Yong Mook Kim" />
        <property name="url" value="http://www.mkyong.com" />
    </bean>

    <bean id="hijackAroundMethodBeanAdvice" class="com.mkyong.aop.HijackAroundMethod" />

    <bean id="customerServiceProxy" 
                class="org.springframework.aop.framework.ProxyFactoryBean">

        <property name="target" ref="customerService" />

        <property name="interceptorNames">
            <list>
                <value>hijackAroundMethodBeanAdvice</value>
            </list>
        </property>
    </bean>
</beans>

文件:HijackAroundMethod.java

package com.mkyong.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.mkyong.common;

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

import com.mkyong.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.mkyong.com
HijackAroundMethod : Before after hijacked!
*************************
Method name : printThrowException
Method arguments : []
HijackAroundMethod : Before method hijacked!
HijackAroundMethod : Throw exception hijacked!

拦截了客户服务类的所有方法。稍后,我们向您展示如何使用“切入点”仅拦截printName()方法。

Pointcuts示例

您可以通过以下两种方式来匹配该方法:

1. Pointcuts – 名称匹配示例

通过“pointcut”和“advisor”拦截printName()方法。
创建一个NameMatchMethodPointcut切入点bean,然后将要拦截的方法名称放在“ mappedName”属性值中。

<bean id="customerPointcut"
        class="org.springframework.aop.support.NameMatchMethodPointcut">
        <property name="mappedName" value="printName" />
</bean>

创建一个DefaultPointcutAdvisor bean,并将advice和pointcut关联。

<bean id="customerAdvisor"
        class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <property name="pointcut" ref="customerPointcut" />
        <property name="advice" ref="hijackAroundMethodBeanAdvice" />
</bean>

将代理的“interceptorNames”替换为“customerAdvisor”(原为“ hijackAroundMethodBeanAdvice”)。

<bean id="customerServiceProxy"
        class="org.springframework.aop.framework.ProxyFactoryBean">

        <property name="target" ref="customerService" />
        
        <property name="interceptorNames">
            <list>
                <value>customerAdvisor</value>
            </list>
        </property>
</bean>

完整的Bean配置文件

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <bean id="customerService" class="com.mkyong.customer.services.CustomerService">
        <property name="name" value="Yong Mook Kim" />
        <property name="url" value="http://www.mkyong.com" />
    </bean>

    <bean id="hijackAroundMethodBeanAdvice" class="com.mkyong.aop.HijackAroundMethod" />

    <bean id="customerServiceProxy" 
                class="org.springframework.aop.framework.ProxyFactoryBean">

        <property name="target" ref="customerService" />

        <property name="interceptorNames">
            <list>
                <value>customerAdvisor</value>
            </list>
        </property>
    </bean>

    <bean id="customerPointcut" 
                class="org.springframework.aop.support.NameMatchMethodPointcut">
        <property name="mappedName" value="printName" />
    </bean>

    <bean id="customerAdvisor" 
                 class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <property name="pointcut" ref="customerPointcut" />
        <property name="advice" ref="hijackAroundMethodBeanAdvice" />
    </bean>

</beans>

再次运行,输出

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

现在,您只拦截了printName()方法。

PointcutAdvisor

Spring附带了PointcutAdvisor类,将advisor和pointcut声明到不同的bean中来保存你的工作,您可以使用NameMatchMethodPointcutAdvisor将两者组合到一个bean中。

<bean id="customerAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
  
   <property name="mappedName" value="printName" />
   <property name="advice">ref="hijackAroundMethodBeanAdvice" />
  
</bean>

2. Pointcut – 正则表达式示例

您还可以使用正则表达式切入点– RegexpMethodPointcutAdvisor来匹配方法的名称。

<bean id="customerAdvisor"
        class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <property name="patterns">
            <list>
                <value>.*URL.*</value>
            </list>
        </property>

        <property name="advice" ref="hijackAroundMethodBeanAdvice" />
</bean>

现在,它拦截了在方法名称中带有单词“ URL”的方法。
实际上,您可以使用它来管理DAO层,在其中可以声明“.* DAO.*”来拦截所有DAO类以支持事务。

上一篇下一篇

猜你喜欢

热点阅读