示例需求:当我们调用fastjson里面的toJSONString方法时,我们在这个方法上加上环绕通知,众所周知,这个方法是第三方jar包fastjson里面提供的一个方法,我们要做的就是切到这个方法上,然后加环绕通知。步骤如下:
1、写一个服务,该服务使用了fastjson里面的toJSONString方法,代码如下:
- public class JSONService {
- public String parse2String(Object obj){
- return JSON.toJSONString(obj);
- }
- }
2、写一个切面,并在该切面上配置环绕通知,代码如下:
- @Aspect
- public class JSONAspect {
- <span style="color:#000099;">public static JSONAspect ajc$perSingletonInstance;
- private static Throwable ajc$initFailureCause;
- static {
- try {
- ajc$postClinit();
- } catch (Throwable localThrowable) {
- ajc$initFailureCause = localThrowable;
- }
- }
- private static void ajc$postClinit() {
- ajc$perSingletonInstance = new JSONAspect();
- }
- public static JSONAspect aspectOf() {
- if (ajc$perSingletonInstance == null)
- throw new NoAspectBoundException("com.chhliu.myself.spring.staticaop.JSONAspect", ajc$initFailureCause);
- return ajc$perSingletonInstance;
- }</span>
- /**
- * attention:
- * Details:切入到第三方jar包对应的具体方法上,同时配置环绕通知
- * @author chhliu
- * 创建时间:2016-7-26 下午5:25:06
- * @param join
- * @param obj
- * @return
- * String
- */
- @Around("execution(* com.alibaba.fastjson.JSON.toJSONString(java.lang.Object)) && args(obj)")
- public String parse2String(ProceedingJoinPoint join, Object obj){
- System.out.println("parse to String before");
- String str = "";
- try {
- str = (String) join.proceed(new Object[]{obj});
- System.out.println("result:"+str);
- } catch (Throwable e) {
- e.printStackTrace();
- }
- System.out.println("parse to String after");
- return str;
- }
- }
注意:代码中标蓝的部分是AspectJ反编译后的代码,必须加上,否则会出问题,切不进去,感觉是spring 整合AspectJ时的一个bug。如果将我们的工程转成AspectJ Project的话,反编译出来的类就会自动的加上上面标蓝的代码。3、在META-INF下增加切面的配置文件,如下:
工程结构目录如下: ![]() |
- <!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
- <aspectj>
- <weaver options="-verbose">
- <!-- 要改变那些包下的类,有@NoWeave注解的会跳过。-->
- <include within="com.alibaba.fastjson.*" />
- </weaver>
- <aspects>
- <!-- 声明的切面 -->
- <aspect name="com.chhliu.myself.spring.staticaop.JSONAspect" />
- </aspects>
- </aspectj>
4、编写测试类,代码如下:
- @RunWith(SpringJUnit4ClassRunner.class)
- @ContextConfiguration(locations = { "classpath:applicationContext.xml" })
- public class JSONAspectTest {
- @Resource(name="jsonService")
- private JSONService service;
- @Test
- public void test(){
- User u = new User();
- u.setName("chhliu");
- u.setPassword("123456");
- service.parse2String(u);
- }
- }
5、增加jvm启动项,在虚拟机启动的时候,就启动AOP切面,如下:6、测试结果如下:
- [AppClassLoader@40d7b9] info AspectJ Weaver Version 1.7.2 built on Friday Feb 15, 2013 at 18:40:45 GMT
- [AppClassLoader@40d7b9] info register classloader sun.misc.Launcher$AppClassLoader@40d7b9
- [AppClassLoader@40d7b9] info using configuration /D:/NTF/spring_test/target/classes/META-INF/aop.xml
- [AppClassLoader@40d7b9] info using configuration file:/D:/SoftWare/java%20software/apache-maven-3.0.5-bin/apache-maven-3.0.5/repository/org/springframework/spring-aspects/3.2.5.RELEASE/spring-aspects-3.2.5.RELEASE.jar!/META-INF/aop.xml
- <span style="color:#3333FF;">[AppClassLoader@40d7b9] info register aspect com.chhliu.myself.spring.staticaop.JSONAspect</span>
- [AppClassLoader@40d7b9] info register aspect org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect
- [AppClassLoader@40d7b9] info register aspect org.springframework.scheduling.aspectj.AnnotationAsyncExecutionAspect
- [AppClassLoader@40d7b9] info register aspect org.springframework.transaction.aspectj.AnnotationTransactionAspect
- [AppClassLoader@40d7b9] info register aspect org.springframework.cache.aspectj.AnnotationCacheAspect
- log4j:WARN No appenders could be found for logger (org.springframework.test.context.junit4.SpringJUnit4ClassRunner).
- log4j:WARN Please initialize the log4j system properly.
- log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
- [AppClassLoader@40d7b9] warning javax.* types are not being woven because the weaver option '-Xset:weaveJavaxPackages=true' has not been specified
- around before
- beforeTest
- parse to String before
- result:{"name":"chhliu","password":"123456"}
- parse to String after
蓝色字体部分说明,在启动的时候,AppClassLoader将我们自己写的切面加载进去了,并且在调用fastjson的toJSONString方法的时候,切面启了作用,如果我们用spring的动态AOP,是很难切入到第三方jar包里面的方法的。从上面的示例中,我们可以看到,使用Spring AOP来实现回归测试是可行的,当我们测试完之后,我们把测试的用例都存起来(文件或Redis),当我们在调用真正方法之前,我们截取该方法的参数,从而获取相关的请求报文信息,然后和Redis中的报文头进行一个匹配,匹配成功之后,我们并不真正的执行目的方法,而是直接将匹配的报文返回给用户,从而实现了mock测试,供大家参考。
联系客服