本文是一个简单的基于注解的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>