Spring AOP入门

     最近读Spring in action后,感觉这本书并没有其描绘的那么轻松幽默,相反很多地方还陷入了迷潭。记得以前上学的时候,读的一本《Spring 2.0技术手册》挺简单的。哎,不过越是不容易的事情越要挑战下,不是吗?

    按照作者的思想,假想有一个Performer表演者。它的定义如下所示:

   

package SpringIdol;

public interface Performer {
       public void performer();
}

 

  其某一个实现类:

  

package SpringIdol;

public class Juggle implements Performer {

	public int bagger=3;
			
	public Juggle() {
		super();
	}

	public Juggle(int bagger) {
		super();
		this.bagger = bagger;
	}

	@Override
	public void performer() {
		System.out.println("Juggle :"+bagger);
	}
	
	public int getBagger() {
		return bagger;
	}

	public void setBagger(int bagger) {
		this.bagger = bagger;
	}
}

 

 

  定义了观众类,并且在performer表演(执行performer)前后做一些规定性的动作。

  表演前落座,关手机,演出完鼓掌,不满意(有异常的时候)要求退票。

  下面就是这个类的定义:

   

package SpringIdol;
public class Audience {
	public Audience(){		
	}
	
	public void takeSeats(){
		System.out.println("I can seat");
	}
	
	public void turnOffTheirPhone(){
		System.out.println("I have turn off phone");
	}

	public void applaud(){
		System.out.println("clap clap clap");
	}
	
	public void demandRefund(){
		System.out.println("No,I want our money back");
	}
}

 下面编写通知类。通知类就是当触发被切入类的切面时所执行的函数,分为触发前执行,触发后执行,以及前后都执行。类的定义如下所示 :

   

package SpringIdol;

//事后返回
import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice; //事前执行 
import org.springframework.aop.MethodBeforeAdvice; //抛出后
import org.springframework.aop.ThrowsAdvice;

public class AudienceAdvice implements AfterReturningAdvice,
		MethodBeforeAdvice, ThrowsAdvice {

	public AudienceAdvice() {
	}

	@Override
	public void afterReturning(Object paramObject1, Method paramMethod,
	    Object[] paramArrayOfObject, Object paramObject2) throws Throwable {
		// 在方法的执行后执行鼓掌函数
		audience.applaud();
	}

	public void before(Method paramMethod, Object[] paramArrayOfObject,
			Object paramObject) throws Throwable {
		// 在执行前,执行落座和关手机两件事
		audience.takeSeats();
		audience.turnOffTheirPhone();
	};

	// 约定的方法之一,用于抛出异常时执行
	public void afterThrowing(Throwable throwable) {
		// 在异常的抛出处,执行退票事件
		audience.demandRefund();
	}
	
	
	private Audience audience;

	public Audience getAudience() {
		return audience;
	}

	public void setAudience(Audience audience) {
		this.audience = audience;
	}
}

  这里的audience将来会通过依赖注入来完成实例化。

  接下来就到了最关键的XML配置。

 

<?xml version="1.0" encoding="utf-8"?>
<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.0.xsd" >
<!-- 定义观众 -->
<bean id="audience" class="SpringIdol.Audience"/>
<!-- 定义主动织入切面的 -->
<bean id="audienceAdvice" class="SpringIdol.AudienceAdvice">
   <property name="audience" ref="audience"></property>
</bean>	
<!-- 繁琐的定义PointCut织入规则 -->
<bean id="performancePointCut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value=".*performer"></property>
</bean>
<bean id="audienceAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
    <!-- 定义通知事件 -->
<property name="advice" ref="audienceAdvice"></property>
    <!-- 定义织入规则 -->
<property name="pointcut" ref="performancePointCut"></property>
</bean>
<!-- 简便的定义PointCut -->
<!-- ProxyFactoryBean -->
<bean id="dukeTarget" class="SpringIdol.PoticJuggle">
    <constructor-arg value="15"></constructor-arg>
</bean>
<bean id="duke" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target" ref="dukeTarget"/>
    <property name="interceptorNames" value="audienceAdvisor"/>
    <property name="proxyInterfaces"      value="SpringIdol.Performer"/> 
</bean>
</beans>

   注意最后面的代理类,它在代理多个类(不同的演出者时)将会有非常大的作用。

   编写一个测试类来测试下:

 

package Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import SpringIdol.Performer;
public class TestAOP {
   public static void main(String... args){
	ApplicationContext context=new ClassPathXmlApplicationContext("SpringAop.xml");
	Performer performer = (Performer)context.getBean("duke");
	performer.performer();
  }
}

    执行结果如下所:

  

I can seat
I have turn off phone
Juggle :15
clap clap clap

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值