Spring AOP 2.0 研究

我们用Hello的例子来诠释Spring AOP 2.0 的特性。
Hello

Java代码 复制代码
  1. public interface Hello {   
  2.     void sayHelloBefore();   
  3.   
  4.     void sayHelloAfter();   
  5.   
  6.     void sayHelloAround();   
  7. }  
public interface Hello {
	void sayHelloBefore();

	void sayHelloAfter();

	void sayHelloAround();
}


SayHello

Java代码 复制代码
  1. public class SayHello implements Hello{   
  2.     /**  
  3.      *   
  4.      */  
  5.     public void sayHelloBefore() {   
  6.         System.out.println("say Hello before!");   
  7.     }   
  8.   
  9.     /**  
  10.      *   
  11.      */  
  12.     public void sayHelloAfter() {   
  13.         System.out.println("say Hello after!");   
  14.     }   
  15.   
  16.     /**  
  17.      *   
  18.      */  
  19.     public void sayHelloAround() {   
  20.         System.out.println("say Hello around!");   
  21.     }   
  22. }  
public class SayHello implements Hello{
	/**
	 * 
	 */
	public void sayHelloBefore() {
		System.out.println("say Hello before!");
	}

	/**
	 * 
	 */
	public void sayHelloAfter() {
		System.out.println("say Hello after!");
	}

	/**
	 * 
	 */
	public void sayHelloAround() {
		System.out.println("say Hello around!");
	}
}


Before

Java代码 复制代码
  1. public class Before {   
  2.     public void invoke(JoinPoint joinPoint) {   
  3.         System.out.println("Before:" + joinPoint.getSignature().getName());   
  4.     }   
  5. }  
public class Before {
	public void invoke(JoinPoint joinPoint) {
		System.out.println("Before:" + joinPoint.getSignature().getName());
	}
}


After

Java代码 复制代码
  1. public class After {   
  2.     public void invoke(JoinPoint joinPoint) {   
  3.     System.out.println("After:" + joinPoint.getSignature().getName());   
  4.     }   
  5. }  
public class After {
	public void invoke(JoinPoint joinPoint) {
	System.out.println("After:" + joinPoint.getSignature().getName());
	}
}


Around

Java代码 复制代码
  1. public class Around {   
  2.     public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {   
  3.         System.out.println("Around:" + joinPoint.getSignature().getName());   
  4.         return joinPoint.proceed();   
  5.     }   
  6. }  
public class Around {
	public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out.println("Around:" + joinPoint.getSignature().getName());
		return joinPoint.proceed();
	}
}


Introduction

Java代码 复制代码
  1. public class Introduction {   
  2.     public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {   
  3.         System.out   
  4.                 .println("Introduction:" + joinPoint.getSignature().getName());   
  5.         return joinPoint.proceed();   
  6.     }   
  7. }  
public class Introduction {
	public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out
				.println("Introduction:" + joinPoint.getSignature().getName());
		return joinPoint.proceed();
	}
}


Introduction 引入的作用在于是一个类在不做任何代码修改的前提下,拥有另一套方法,或者说具备另一套本领,比如我们现在就想让这个实现了Hello接口的SayHello类拥有Ok接口的方法

Java代码 复制代码
  1. public interface Ok {   
  2.     void sayOk();   
  3. }  
public interface Ok {
	void sayOk();
}


IntroductionOk  首先要解决上述接口Ok的实现

Java代码 复制代码
  1. public class IntroductionOk implements Ok {   
  2.     
  3.     @Override  
  4.     public void sayOk() {   
  5.         System.out.println("Ok!");   
  6.     }   
  7. }  
public class IntroductionOk implements Ok {
 
	@Override
	public void sayOk() {
		System.out.println("Ok!");
	}
}


AllTest

Java代码 复制代码
  1. public class AllTest {   
  2.     private ApplicationContext app;   
  3.   
  4.     /**  
  5.      * @throws java.lang.Exception  
  6.      */  
  7.     @Before  
  8.     public void setUp() throws Exception {   
  9.         app = new ClassPathXmlApplicationContext("applicationContext.xml");   
  10.     }   
  11.   
  12.     @Test  
  13.     public final void testHello() {   
  14.         Hello hello = (Hello) app.getBean("hello");   
  15.         hello.sayHelloBefore();   
  16.         hello.sayHelloAfter();   
  17.         hello.sayHelloAround();   
  18.   
  19.         // 由于对Hello接口进行了引入,   
  20.         // 使得实现了Hello接口的类可以具备Ok接口的功能。   
  21.         // 同时,我们可以拦截这个方法让他执行其他我们需要执行的操作   
  22.         hello.sayHelloIntroduction();   
  23.         ((Ok) hello).sayOk();   
  24.     }   
  25.   
  26. }  
public class AllTest {
	private ApplicationContext app;

	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		app = new ClassPathXmlApplicationContext("applicationContext.xml");
	}

	@Test
	public final void testHello() {
		Hello hello = (Hello) app.getBean("hello");
		hello.sayHelloBefore();
		hello.sayHelloAfter();
		hello.sayHelloAround();

		// 由于对Hello接口进行了引入,
		// 使得实现了Hello接口的类可以具备Ok接口的功能。
		// 同时,我们可以拦截这个方法让他执行其他我们需要执行的操作
		hello.sayHelloIntroduction();
		((Ok) hello).sayOk();
	}

}


关于表达式符号
.*+定义目标为包下的所有类
+定义目标为该接口的所有实现类

Xml代码 复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans  
  3.     xmlns="http://www.springframework.org/schema/beans"  
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.     xmlns:aop="http://www.springframework.org/schema/aop"  
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd   
  7.         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">  
  8.     <bean  
  9.         id="hello"  
  10.         class="org.zlex.aop.SayHello" />  
  11.     <!-- after -->  
  12.     <bean  
  13.         id="after"  
  14.         class="org.zlex.aop.After" />  
  15.     <aop:config>  
  16.         <aop:pointcut  
  17.             id="afterPoint"  
  18.             expression="execution(* org.zlex.aop.Hello.sayHelloAfter(..))" />  
  19.         <aop:aspect  
  20.             id="afterAspect"  
  21.             ref="after">  
  22.             <aop:after  
  23.                 method="invoke"  
  24.                 pointcut-ref="afterPoint" />  
  25.         </aop:aspect>  
  26.     </aop:config>  
  27.     <!-- before -->  
  28.     <bean  
  29.         id="before"  
  30.         class="org.zlex.aop.Before" />  
  31.     <aop:config>  
  32.         <aop:pointcut  
  33.             id="beforePoint"  
  34.             expression="execution(* org.zlex.aop.Hello.sayHelloBefore(..))" />  
  35.         <aop:aspect  
  36.             id="beforeAspect"  
  37.             ref="before">  
  38.             <aop:before  
  39.                 method="invoke"  
  40.                 pointcut-ref="beforePoint" />  
  41.         </aop:aspect>  
  42.     </aop:config>  
  43.     <!-- around -->  
  44.     <bean  
  45.         id="around"  
  46.         class="org.zlex.aop.Around" />  
  47.     <aop:config>  
  48.         <aop:pointcut  
  49.             id="aroundPoint"  
  50.             expression="execution(* org.zlex.aop.Hello.sayHelloAround(..))" />  
  51.         <aop:aspect  
  52.             id="aroundAspect"  
  53.             ref="around">  
  54.             <aop:around  
  55.                 method="invoke"  
  56.                 pointcut-ref="aroundPoint" />  
  57.         </aop:aspect>  
  58.     </aop:config>  
  59.     <!-- introduction -->  
  60.     <!--    
  61.     .*+是用于包下的,不是用于接口   
  62.     +定义目标为该接口的所有实现类   
  63.      -->  
  64.     <bean  
  65.         id="introduction"  
  66.         class="org.zlex.aop.Introduction" />  
  67.     <bean  
  68.         id="introductionOk"  
  69.         class="org.zlex.aop.IntroductionOk" />  
  70.     <aop:config>  
  71.         <aop:aspect  
  72.             ref="introduction">  
  73.             <aop:pointcut  
  74.                 id="introductionPoint"  
  75.                 expression="execution(* org.zlex.aop.Hello.sayHelloIntroduction(..))" />  
  76.             <aop:declare-parents  
  77.                 implement-interface="org.zlex.aop.Ok"  
  78.                 types-matching="org.zlex.aop.Hello+"  
  79.                 delegate-ref="introductionOk" />  
  80.             <aop:around  
  81.                 method="invoke"  
  82.                 pointcut-ref="introductionPoint" />  
  83.         </aop:aspect>  
  84.     </aop:config>  
  85. </beans>  
<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
	<bean
		id="hello"
		class="org.zlex.aop.SayHello" />
	<!-- after -->
	<bean
		id="after"
		class="org.zlex.aop.After" />
	<aop:config>
		<aop:pointcut
			id="afterPoint"
			expression="execution(* org.zlex.aop.Hello.sayHelloAfter(..))" />
		<aop:aspect
			id="afterAspect"
			ref="after">
			<aop:after
				method="invoke"
				pointcut-ref="afterPoint" />
		</aop:aspect>
	</aop:config>
	<!-- before -->
	<bean
		id="before"
		class="org.zlex.aop.Before" />
	<aop:config>
		<aop:pointcut
			id="beforePoint"
			expression="execution(* org.zlex.aop.Hello.sayHelloBefore(..))" />
		<aop:aspect
			id="beforeAspect"
			ref="before">
			<aop:before
				method="invoke"
				pointcut-ref="beforePoint" />
		</aop:aspect>
	</aop:config>
	<!-- around -->
	<bean
		id="around"
		class="org.zlex.aop.Around" />
	<aop:config>
		<aop:pointcut
			id="aroundPoint"
			expression="execution(* org.zlex.aop.Hello.sayHelloAround(..))" />
		<aop:aspect
			id="aroundAspect"
			ref="around">
			<aop:around
				method="invoke"
				pointcut-ref="aroundPoint" />
		</aop:aspect>
	</aop:config>
	<!-- introduction -->
	<!-- 
	.*+是用于包下的,不是用于接口
	+定义目标为该接口的所有实现类
	 -->
	<bean
		id="introduction"
		class="org.zlex.aop.Introduction" />
	<bean
		id="introductionOk"
		class="org.zlex.aop.IntroductionOk" />
	<aop:config>
		<aop:aspect
			ref="introduction">
			<aop:pointcut
				id="introductionPoint"
				expression="execution(* org.zlex.aop.Hello.sayHelloIntroduction(..))" />
			<aop:declare-parents
				implement-interface="org.zlex.aop.Ok"
				types-matching="org.zlex.aop.Hello+"
				delegate-ref="introductionOk" />
			<aop:around
				method="invoke"
				pointcut-ref="introductionPoint" />
		</aop:aspect>
	</aop:config>
</beans>


执行查看日志:

引用

Before:sayHelloBefore
say SayHello before!
say Hello after!
After:sayHelloAfter
Around:sayHelloAround
say Hello around!
Introduction:sayHelloIntroduction
say Hello introduction!
Ok!


仔细观察

引用

Before:sayHelloBefore
say Hello before!


在输出say Hello before!前输出Before:sayHelloBefore

引用

say Hello after!
After:sayHelloAfter


在输出say Hello after!后输出After:sayHelloAfter
Around比较特殊,可以用ProceedingJoinPoint调用proceed()方法

引用

Around:sayHelloAround
say Hello around!

 

引用

Introduction:sayHelloIntroduction
say Hello introduction!
Ok!


同样是Hello接口,在执行了sayHelloIntroduction方法时被拦截,同时输出say Hello introduction!,此时还可以执行Ok的方法输出

引用
Ok!

。显然,Hello的实现类多了Ok接口的本领。
Spring Beans 结构图如下:

如此这样,就可以控制AOP了,当前资料少,实例也少,继续研究!希望能做出来点实际的东西。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值