【Spring】Spring 3.x企业应用开发实战(10)----AOP切面

1、静态普通方法名匹配切面

StaticMethodMatcherPointcutAdvisor代表一个静态方法匹配切面。

 

package com.smart.advisor;

public class Waiter 
{
	public void greetTo(String name)
	{
		System.out.println("Waiter greet to "+name+"...");
	}
	
	public void serveTo(String name)
	{
		System.out.println("Waiter serving "+name+"...");
	}
}

 

package com.smart.advisor;

public class Seller 
{
	public void greetTo(String name)
	{
		System.out.println("Seller greet to "+name+"...");
	}
}

 

package com.smart.advisor;

import java.lang.reflect.Method;

import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;

public class GreetingAdvisor extends StaticMethodMatcherPointcutAdvisor
{

	private static final long serialVersionUID = 1L;

	@Override
	public boolean matches(Method arg0, Class<?> arg1) {
		//切點方法匹配規則:方法名為greetTo
		// TODO Auto-generated method stub
		return "greetTo".equals(arg0.getName());
	}

	@Override
	public ClassFilter getClassFilter() {
		//切點類匹配匹配規則:為Waiter的類或子類
		// TODO Auto-generated method stub
		return new ClassFilter() {			
			@Override
			public boolean matches(Class<?> clazz) {
				// TODO Auto-generated method stub
				return Waiter.class.isAssignableFrom(clazz);
			}
		};
	}

	
}

 

package com.smart.advisor;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class GreetingBeforeAdvice implements MethodBeforeAdvice
{

	@Override
	public void before(Method arg0, Object[] arg1, Object arg2)
			throws Throwable {
		// TODO Auto-generated method stub
		System.out.println(arg2.getClass().getName()+"."+arg0.getName());//輸出切點
		String clientName=(String)arg1[0];
		System.out.println("How are you ! Mr."+clientName+".");		
	}	
}

 

<bean id="waiterTarget" class="com.smart.advisor.Waiter"/>
	<bean id="sellerTarget" class="com.smart.advisor.Seller"/>
	<bean id="greetingAdvice" class="com.smart.advisor.GreetingBeforeAdvice"/>
	<bean id="greetingAdvisor" class="com.smart.advisor.GreetingAdvisor"
			p:advice-ref="greetingAdvice"/><!-- 向切面注入前置加强 -->
	<bean id="parent" abstract="true"
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:interceptorNames="greetingAdvisor"
		p:proxyTargetClass="true"/><!-- abstract="true" 通過一個父<bean>定義公共的配置信息 -->
	<bean id="waiter" parent="parent" p:target-ref="waiterTarget"/><!-- waiter代理 -->
	<bean id="seller" parent="parent" p:target-ref="sellerTarget"/><!-- seller代理 -->

 

package com.smart.advisor;

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

public class SpringAdvisorTest 
{
	@Test
	public void testAdvisor()
	{
		String configPath="com/smart/advisor/beans.xml";
		ApplicationContext ctx=new ClassPathXmlApplicationContext(configPath);
		Waiter waiter=(Waiter)ctx.getBean("waiter");
		Seller seller=(Seller)ctx.getBean("seller");		
		waiter.greetTo("TomSon");
		waiter.serveTo("TomSon");		
		seller.greetTo("TomSon");
	}
}

 

得到结果:

 

com.smart.advisor.Waiter.greetTo
How are you ! Mr.TomSon.
Waiter greet to TomSon...
Waiter serving TomSon...
Seller greet to TomSon...

可见,切面只织入Waiter.greetTo()方法调用前的连接点上,Waiter.serveTo()和Seller.greetTo()方法没有织入切面。

2、静态正则表达式方法匹配切面

具体事例:

beans2.xml

 

<bean id="waiterTarget" class="com.smart.advisor.Waiter"/>
	<bean id="sellerTarget" class="com.smart.advisor.Seller"/>
	<bean id="greetingAdvice" class="com.smart.advisor.GreetingBeforeAdvice"/>
	<bean id="regexAdvisor" 
			class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"
			p:advice-ref="greetingAdvice">
			<property name="patterns"><!--用正则表达式定义目标类全限定方法名匹配模式串-->
				<list>
					<value>.*greet.*</value><!-- 匹配模式串 -->
				</list>
			</property>
	</bean>
	<bean id="waiter1" class="org.springframework.aop.framework.ProxyFactoryBean"
		p:interceptorNames="regexAdvisor"
		p:target-ref="waiterTarget"
		p:proxyTargetClass="true"/>

定义了一个匹配模式串".*greet.*",该模式串匹配Waiter.greetTo()方法。

 

 

测试数据:

 

package com.smart.advisor;

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

public class SpringAdvisorTest 
{
	@Test
	public void testAdvisor()
	{
		String configPath="com/smart/advisor/beans2.xml";
		ApplicationContext ctx=new ClassPathXmlApplicationContext(configPath);
		Waiter waiter=(Waiter)ctx.getBean("waiter1");		
		waiter.greetTo("Tom");
		waiter.serveTo("Tom");
		
	}
}


显示结果是:

 

com.smart.advisor.Waiter.greetTo
How are you ! Mr.Tom.
Waiter greet to Tom...
Waiter serving Tom...

 

3、自动创建代理:

BeanNameAutoProxyCreator实例:

beans3.xml

<bean id="waiterTarget" class="com.smart.advisor.Waiter"/>
	<bean id="sellerTarget" class="com.smart.advisor.Seller"/>
	<bean id="greetingAdvice" class="com.smart.advisor.GreetingBeforeAdvice"/>
	
	<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"
			p:beanNames="*erTarget"
			p:interceptorNames="greetingAdvice"
			p:optimize="true"/>


测试数据:

 

 

package com.smart.advisor;

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

public class SpringAdvisorTest 
{
	@Test
	public void testAdvisor()
	{		
		String configPath="com/smart/advisor/beans3.xml";
		ApplicationContext ctx=new ClassPathXmlApplicationContext(configPath);	
		Waiter waiter=(Waiter)ctx.getBean("waiterTarget");
		Seller seller=(Seller)ctx.getBean("sellerTarget");
		waiter.greetTo("John");
		seller.greetTo("Tom");
	}
}

结果数据是:

 

com.smart.advisor.Waiter.greetTo
How are you ! Mr.John.
Waiter greet to John...
com.smart.advisor.Seller.greetTo
How are you ! Mr.Tom.
Seller greet to Tom...

DefaultAdvisorAutoProxyCreator实例:

DefaultAdvisorAutoProxyCreator能够扫描容器中的Advisor,并将Advisor自动织入匹配的目标Bean中,即为匹配的目标Bean自动创建代理。

beans4.xml

 

<bean id="waiterTarget" class="com.smart.advisor.Waiter"/>
	<bean id="sellerTarget" class="com.smart.advisor.Seller"/>
	<bean id="greetingAdvice" class="com.smart.advisor.GreetingBeforeAdvice"/>
	
	<bean id="regexpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"
			p:patterns=".*greet.*"
			p:advice-ref="greetingAdvice"
	/>
	
	<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
	<!-- 用DefaultAdvisorAutoProxyCreator定義一個Bean,他負責將容器中的Advisor織入匹配的目標Bean中。 -->

 

 

测试数据:

 

package com.smart.advisor;

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

public class SpringAdvisorTest 
{
	@Test
	public void testAdvisor()
	{		
		String configPath="com/smart/advisor/beans4.xml";
		ApplicationContext ctx=new ClassPathXmlApplicationContext(configPath);
		
		Waiter waiter=(Waiter)ctx.getBean("waiterTarget");
		Seller seller=(Seller)ctx.getBean("sellerTarget");
		
		waiter.serveTo("John");
		waiter.greetTo("John");
		seller.greetTo("Tom");
	}
}

 

得到的结果是:

 

Waiter serving John...
com.smart.advisor.Waiter.greetTo
How are you ! Mr.John.
Waiter greet to John...
com.smart.advisor.Seller.greetTo
How are you ! Mr.Tom.
Seller greet to Tom...

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值