1. 程式人生 > >Spring AOP修改函式返回值

Spring AOP修改函式返回值

最近boss叫我用spring aop做一個試驗,說是之後一個新專案要用到,大體需求如下:攔截某個函式的返回值,並修改之。

    因為之前我對AOP的認識只是停留在上課時老師跟我們傳授的理論階段,從未寫過程式碼實踐過,因此這次我花了一定的時間去做了這個試驗。一開始打算上網直接查詢相關程式碼,但是發覺都沒有達到我預期的效果,於是決定自己寫一個。一開始我打算用後置增強來解決,但是發現只能獲取返回值,並不能改變它,之後在stackOverflow問了一下,經過一個網友的提示,終於fix掉了,核心是用環繞增強和ProceedingJoinPoint,廢話少說,直接貼程式碼

定義目標業務類

public class AopDemo implements IAopDemo{

	public String doSth(String task){
		System.out.println("do somthing.........."+task);
		return task;
	}
定義切面,引數ProceedingJoinPoint 通過直接列印pjp,會看到控制檯輸出一句execution(String com.toby.aop.IAopDemo.doSth(String)),說明pjp是當前被呼叫的切點方法的引用
public class Listener {

	public Object around(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("beginning----"); 
		Object object = pjp.proceed();    //執行doSth(),返回值用一個Object型別來接收
		object = "Mission Two";   //改變返回值
	    System.out.println("ending----");
		return object;    
	}
}
配置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"
		xmlns:util="http://www.springframework.org/schema/util"
		xmlns:context="http://www.springframework.org/schema/context"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xmlns:aop="http://www.springframework.org/schema/aop"
		
		xsi:schemaLocation="http://www.springframework.org/schema/beans 
			http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
			http://www.springframework.org/schema/tx  
            http://www.springframework.org/schema/tx/spring-tx.xsd  
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
			http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">

	<bean id="aopDemo" class="com.toby.aop.AopDemo"/>
	<bean id="listener" class="com.toby.aop.Listener"/>
    <aop:config>
    	<aop:aspect id="myListener" ref="listener">
 <aop:pointcut expression="execution(* com.toby.aop.AopDemo.*(..))" id="listenerCut"/>
    		
    		 <aop:around method="around" pointcut-ref="listenerCut"/> 
    	</aop:aspect> 
    </aop:config>	
</beans>
測試
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context-common.xml");
		IAopDemo demo = (IAopDemo)context.getBean("aopDemo");
		System.out.println(demo.doSth("Mission One"));

程式執行結果 

    beginning----

    do somthing..........Mission One

    ending----

    Mission Two

   呼叫doSth()後,@Around定義的around()方法裡通過攔截返回值"Mission One",並修改為“Mission Two”返回,也就是說,doSth的返回值最後其實是around()的返回值

如果有更好的方法,也歡迎賜教,大家互相學習!