分享

spring静态AOP切第三方jar包

 廖知 2020-06-09

示例需求:当我们调用fastjson里面的toJSONString方法时,我们在这个方法上加上环绕通知,众所周知,这个方法是第三方jar包fastjson里面提供的一个方法,我们要做的就是切到这个方法上,然后加环绕通知。步骤如下:

1、写一个服务,该服务使用了fastjson里面的toJSONString方法,代码如下:

  1. public class JSONService {
  2. public String parse2String(Object obj){
  3. return JSON.toJSONString(obj);
  4. }
  5. }

2、写一个切面,并在该切面上配置环绕通知,代码如下:

  1. @Aspect
  2. public class JSONAspect {
  3. <span style="color:#000099;">public static JSONAspect ajc$perSingletonInstance;
  4. private static Throwable ajc$initFailureCause;
  5. static {
  6. try {
  7. ajc$postClinit();
  8. } catch (Throwable localThrowable) {
  9. ajc$initFailureCause = localThrowable;
  10. }
  11. }
  12. private static void ajc$postClinit() {
  13. ajc$perSingletonInstance = new JSONAspect();
  14. }
  15. public static JSONAspect aspectOf() {
  16. if (ajc$perSingletonInstance == null)
  17. throw new NoAspectBoundException("com.chhliu.myself.spring.staticaop.JSONAspect", ajc$initFailureCause);
  18. return ajc$perSingletonInstance;
  19. }</span>
  20. /**
  21. * attention:
  22. * Details:切入到第三方jar包对应的具体方法上,同时配置环绕通知
  23. * @author chhliu
  24. * 创建时间:2016-7-26 下午5:25:06
  25. * @param join
  26. * @param obj
  27. * @return
  28. * String
  29. */
  30. @Around("execution(* com.alibaba.fastjson.JSON.toJSONString(java.lang.Object)) && args(obj)")
  31. public String parse2String(ProceedingJoinPoint join, Object obj){
  32. System.out.println("parse to String before");
  33. String str = "";
  34. try {
  35. str = (String) join.proceed(new Object[]{obj});
  36. System.out.println("result:"+str);
  37. } catch (Throwable e) {
  38. e.printStackTrace();
  39. }
  40. System.out.println("parse to String after");
  41. return str;
  42. }
  43. }
注意:代码中标蓝的部分是AspectJ反编译后的代码,必须加上,否则会出问题,切不进去,感觉是spring 整合AspectJ时的一个bug。如果将我们的工程转成AspectJ Project的话,反编译出来的类就会自动的加上上面标蓝的代码。

3、在META-INF下增加切面的配置文件,如下:

工程结构目录如下:


  1. <!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www./aspectj/dtd/aspectj.dtd">
  2. <aspectj>
  3. <weaver options="-verbose">
  4. <!-- 要改变那些包下的类,有@NoWeave注解的会跳过。-->
  5. <include within="com.alibaba.fastjson.*" />
  6. </weaver>
  7. <aspects>
  8. <!-- 声明的切面 -->
  9. <aspect name="com.chhliu.myself.spring.staticaop.JSONAspect" />
  10. </aspects>
  11. </aspectj>

4、编写测试类,代码如下:

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration(locations = { "classpath:applicationContext.xml" })
  3. public class JSONAspectTest {
  4. @Resource(name="jsonService")
  5. private JSONService service;
  6. @Test
  7. public void test(){
  8. User u = new User();
  9. u.setName("chhliu");
  10. u.setPassword("123456");
  11. service.parse2String(u);
  12. }
  13. }
5、增加jvm启动项,在虚拟机启动的时候,就启动AOP切面,如下:

6、测试结果如下:

  1. [AppClassLoader@40d7b9] info AspectJ Weaver Version 1.7.2 built on Friday Feb 15, 2013 at 18:40:45 GMT
  2. [AppClassLoader@40d7b9] info register classloader sun.misc.Launcher$AppClassLoader@40d7b9
  3. [AppClassLoader@40d7b9] info using configuration /D:/NTF/spring_test/target/classes/META-INF/aop.xml
  4. [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
  5. <span style="color:#3333FF;">[AppClassLoader@40d7b9] info register aspect com.chhliu.myself.spring.staticaop.JSONAspect</span>
  6. [AppClassLoader@40d7b9] info register aspect org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect
  7. [AppClassLoader@40d7b9] info register aspect org.springframework.scheduling.aspectj.AnnotationAsyncExecutionAspect
  8. [AppClassLoader@40d7b9] info register aspect org.springframework.transaction.aspectj.AnnotationTransactionAspect
  9. [AppClassLoader@40d7b9] info register aspect org.springframework.cache.aspectj.AnnotationCacheAspect
  10. log4j:WARN No appenders could be found for logger (org.springframework.test.context.junit4.SpringJUnit4ClassRunner).
  11. log4j:WARN Please initialize the log4j system properly.
  12. log4j:WARN See http://logging./log4j/1.2/faq.html#noconfig for more info.
  13. [AppClassLoader@40d7b9] warning javax.* types are not being woven because the weaver option '-Xset:weaveJavaxPackages=true' has not been specified
  14. around before
  15. beforeTest
  16. parse to String before
  17. result:{"name":"chhliu","password":"123456"}
  18. parse to String after
蓝色字体部分说明,在启动的时候,AppClassLoader将我们自己写的切面加载进去了,并且在调用fastjson的toJSONString方法的时候,切面启了作用,如果我们用spring的动态AOP,是很难切入到第三方jar包里面的方法的。

从上面的示例中,我们可以看到,使用Spring AOP来实现回归测试是可行的,当我们测试完之后,我们把测试的用例都存起来(文件或Redis),当我们在调用真正方法之前,我们截取该方法的参数,从而获取相关的请求报文信息,然后和Redis中的报文头进行一个匹配,匹配成功之后,我们并不真正的执行目的方法,而是直接将匹配的报文返回给用户,从而实现了mock测试,供大家参考。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多