Spring AOP实例(Pointcut,Advisor)

广告位

在上一个SpringAOP通知的例子,一个类的整个方法被自动拦截。但在大多数情况下,可能只需要一种方式来拦截一…

在上一个SpringAOP通知的例子,一个类的整个方法被自动拦截。但在大多数情况下,可能只需要一种方式来拦截一个或两个方法,这就是为什么引入’切入点’的原因。它允许你通过它的方法名来拦截方法。另外,一个“切入点”必须具有“Advisor’ 相关联。

在SpringAOP中,有三个非常专业术语-Advices,Yiibaicut,Advisor,把它在非官方的方式…
  • Advice –指示之前或方法执行后采取的行动。
  • Yiibaicut –指明哪些方法应该拦截,通过方法的名称或正则表达式模式。
  • Advisor –分组”通知”和”切入点“成为一个单元,并把它传递到代理工厂对象。

再次回顾上一个。

File : CustomerService.java

package com.yiibai.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();  	}  	  }

File : applicationContext.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.yiibai.customer.services.CustomerService">  		<property name="name" value="Yong Mook Kim" />  		<property name="url" value="http://www.yiibai.com" />  	</bean>    	<bean id="hijackAroundMethodBeanAdvice" class="com.yiibai.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>

File : HijackAroundMethod.java

package com.yiibai.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.yiibai.common;    import org.springframework.context.ApplicationContext;  import org.springframework.context.support.ClassPathXmlApplicationContext;    import com.yiibai.customer.services.CustomerService;    public class App {  	public static void main(String[] args) {  		ApplicationContext appContext = new ClassPathXmlApplicationContext(  				new String[] { "applicationContext.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 : Yiibai  HijackAroundMethod : Before after hijacked!  *************************  Method name : printURL  Method arguments : []  HijackAroundMethod : Before method hijacked!  Customer website : http://www.yiibai.com  HijackAroundMethod : Before after hijacked!  *************************  Method name : printThrowException  Method arguments : []  HijackAroundMethod : Before method hijacked!  HijackAroundMethod : Throw exception hijacked!
客户服务类的全部方法被截获。后来,我们展示如何使用“切入点”只拦截printName()方法。

切入点的例子

可以通过以下两种方式相匹配的方法:
  1. 名称匹配
  2. 正则表达式匹配

1.切入点-名称匹配的例子

通过“切入点”和“advisor”拦截printName()方法。创建NameMatchMethodYiibaicut切入点bean,并提出要在“mappedName”属性值来拦截方法名。
<bean id="customerYiibaicut"          class="org.springframework.aop.support.NameMatchMethodYiibaicut">  		<property name="mappedName" value="printName" />  	</bean>
创建 DefaultYiibaicutAdvisor 通知 bean,通知和切入点相关联。
<bean id="customerAdvisor"  		class="org.springframework.aop.support.DefaultYiibaicutAdvisor">  		<property name="pointcut" ref="customerYiibaicut" />  		<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.yiibai.customer.services.CustomerService">  		<property name="name" value="Yiibai" />  		<property name="url" value="http://www.yiibai.com" />  	</bean>    	<bean id="hijackAroundMethodBeanAdvice" class="com.yiibai.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="customerYiibaicut"                   class="org.springframework.aop.support.NameMatchMethodYiibaicut">  		<property name="mappedName" value="printName" />  	</bean>    	<bean id="customerAdvisor"                    class="org.springframework.aop.support.DefaultYiibaicutAdvisor">  		<property name="pointcut" ref="customerYiibaicut" />  		<property name="advice" ref="hijackAroundMethodBeanAdvice" />  	</bean>    </beans>
再次运行,输出
*************************  Method name : printName  Method arguments : []  HijackAroundMethod : Before method hijacked!  Customer name : Yiibai  HijackAroundMethod : Before after hijacked!  *************************  Customer website : http://www.yiibai.com  *************************
现在,只拦截 printName()方法。
YiibaicutAdvisor

Spring提供了YiibaicutAdvisor类来保存工作声明advisor和切入点到不同的bean,可以使用NameMatchMethodYiibaicutAdvisor两者结合成一个bean。
<bean id="customerAdvisor"  		class="org.springframework.aop.support.NameMatchMethodYiibaicutAdvisor">  	  		<property name="mappedName" value="printName" />  		<property name="advice" ref="hijackAroundMethodBeanAdvice" />  	  	</bean>

2.切入点-正则表达式的例子

也可以通过使用正则表达式匹配切入点方法的名称–RegexpMethodYiibaicutAdvisor.

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

现在,它拦截方法名称中有“URL”的方法。在实践中,可以用它来管理DAO层,声明“.*DAO.*”拦截所有的DAO类来支持事务。

下载代码 –

贺, 贺朝

关于作者: 贺朝

为您推荐