Spring基於註解的AOP測試

yingxian_Fei發表於2017-04-26

本文是一個簡單的基於註解的AOP測試例子。本文中的例子在不使用AOP時正常用於輸出一句“I want make a friend with you.”。使用AOP後對返回的訊息在中間進行了強制修改,最後輸出為“I want fuck you!”的字樣。就比如好好的一封情書,在傳遞過程中被人篡改,變成了一句很汙的話,寫情書的人形象全毀了,但是它卻不知道。而這個篡改資訊的就是AOP。

1、正常的業務處理

原來的情書原始碼如下,在這個類中返回了一句"我想和你交個朋友"的話語。

package cn.landsem.handler;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

@Component
public class BusinessHandler {
	private Logger logger = Logger.getLogger(BusinessHandler.class);
	public String say() {
		logger.info("I want make a friend with you.");
		return "I want make a friend with you.";
	}
}

2、AOP

AOP是個壞人,它悄悄監視了BusinessHandler的動作,並攔截和篡改了它寫的情書,將它要說的話改成了“我想操你!”。原始碼如下:

package cn.landsem.aop;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class BusinessAop {
    @SuppressWarnings("unused")
    private Logger logger = Logger.getLogger(BusinessAop.class);
    
    @Pointcut("execution(** cn.landsem.handler.BusinessHandler.say(..))")
    public void cutpoint(){}
    
    @Around("cutpoint()")
    public String test(ProceedingJoinPoint jp) throws Throwable {
        jp.proceed();
        return "I want fuck you!";
    }

}


當然本例中的AOP還呼叫了jp.proceed();將控制權交給了正常的業務處理,即還是讓他來寫一會,之後不顧情面修改了返回的內容。實際使用中這裡可以呼叫其他的方法或者乾脆啥也不幹。

3、java的配置類

在java類中配置AOP以及完成bean的自動掃描,原始碼如下:

package cn.landsem.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

import cn.landsem.aop.BusinessAop;

@Configuration
@EnableAspectJAutoProxy
@ComponentScan("cn.landsem.handler")
public class RootConfiguration {

	@Bean
	public BusinessAop businessAop() {
		return new BusinessAop();
	}
}

4、測試用例

測試用例如下:

package cn.landsem.aop;

import org.apache.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

import cn.landsem.configuration.RootConfiguration;
import cn.landsem.handler.BusinessHandler;

@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration(classes = {RootConfiguration.class})   
@WebAppConfiguration 
public class BaseTest {
	private Logger logger = Logger.getLogger(BaseTest.class);

	@Autowired
	private BusinessHandler mHandler;
	
	@Test
	public void test() {
		logger.info(mHandler.say());
	}
}


注意:

如果在執行時出現瞭如下的錯誤:

::0 can't find referenced pointcut 

這個並不是由於程式碼有問題,而是由於開發環境中以來的jar包版本不匹配導致,可以參考http://tonydzl-2008.iteye.com/blog/2176653中給出的解決方法修改使用對應的jar包即可。

本文中的配置方法如下:

(1)、在MyEclipse中選中工程使用alt+Enter快捷鍵開啟屬性,選擇Java compiler,修改使用的jdk版本(本文使用了1.7的版本);

(2)、在maven的pom.xml檔案中修改如下依賴的jar版本(本文使用1.7.3的版本):

		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>1.7.3</version>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.7.3</version>
		</dependency>


相關文章