SpringAop源码及调用过程概述
1.源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public class TestAop { public static void main(String[] args) throws Exception { saveGeneratedCGlibProxyFiles(System.getProperty( "user.dir" ) + "/proxy" ); ApplicationContext ac = new ClassPathXmlApplicationContext( "META-INF/aop.xml" ); MyCalculator bean = ac.getBean(MyCalculator. class ); System.out.println(bean.toString()); bean.add( 1 , 1 ); bean.sub( 1 , 1 ); } public static void saveGeneratedCGlibProxyFiles(String dir) throws Exception { Field field = System. class .getDeclaredField( "props" ); field.setAccessible( true ); Properties props = (Properties) field.get( null ); //dir为保存文件路径 System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, dir); props.put( "net.sf.cglib.core.DebuggingClassWriter.traceEnabled" , "true" ); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | public class MyCalculator /*implements Calculator */ { public Integer add(Integer i, Integer j) throws NoSuchMethodException { Integer result = i + j; System.out.println( "MyCalculator add method invoked" ); return result; } public Integer sub(Integer i, Integer j) throws NoSuchMethodException { Integer result = i - j; return result; } public Integer mul(Integer i, Integer j) throws NoSuchMethodException { Integer result = i * j; return result; } public Integer div(Integer i, Integer j) throws NoSuchMethodException { Integer result = i / j; return result; } public Integer show(Integer i) { System.out.println( "show ....." ); return i; } @Override public String toString() { return "super.toString()" ; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | public class LogUtil { private int start(JoinPoint joinPoint) { //获取方法签名 Signature signature = joinPoint.getSignature(); //获取参数信息 Object[] args = joinPoint.getArgs(); System.out.println( "log---Before advice: " + signature.getName() + "方法开始执行:参数是" + Arrays.asList(args)); return 100 ; } public static void stop(JoinPoint joinPoint, Object result) { Signature signature = joinPoint.getSignature(); System.out.println( "log---AfterReturning advice: " + signature.getName() + "方法执行结束,结果是:" + result); } public static void logException(JoinPoint joinPoint, Exception e) { Signature signature = joinPoint.getSignature(); System.out.println( "log--- AfterThrowing advice: " + signature.getName() + "方法抛出异常:" + e.getMessage()); } public static void logFinally(JoinPoint joinPoint) { Signature signature = joinPoint.getSignature(); System.out.println( "log---After advice: " + signature.getName() + "方法执行结束。。。。。over" ); } public Object around(ProceedingJoinPoint pjp) throws Throwable { Signature signature = pjp.getSignature(); Object[] args = pjp.getArgs(); Object result = null ; try { System.out.println( "log---Around advice start:" + signature.getName() + "方法开始执行,参数为:" + Arrays.asList(args)); //通过反射的方式调用目标的方法,相当于执行method.invoke(),可以自己修改结果值 result = pjp.proceed(args); // result=100; System.out.println( "log---Around advice end: " + signature.getName() + "方法执行结束" ); } catch (Throwable throwable) { System.out.println( "log---Around advice error:" + signature.getName() + "出现异常" ); throw throwable; } finally { System.out.println( "log---Around advice finally:" + signature.getName() + "方法返回结果是:" + result); } return result; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <? 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:aop = "http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <!-- <bean class="com.mashibing.MyBeanFactoryPostProcessorBySelf" ></bean>--> < bean id = "logUtil" class = "org.geekbang.thinking.in.spring.ioc.overview.aop.xml.util.LogUtil" ></ bean > < bean id = "myCalculator" class = "org.geekbang.thinking.in.spring.ioc.overview.aop.xml.service.MyCalculator" ></ bean > < aop:config > < aop:aspect ref = "logUtil" > < aop:pointcut id = "myPoint" expression = "execution( Integer org.geekbang.thinking.in.spring.ioc.overview.aop.xml.service.MyCalculator.* (..))" /> < aop:around method = "around" pointcut-ref = "myPoint" ></ aop:around > < aop:after method = "logFinally" pointcut-ref = "myPoint" ></ aop:after > < aop:before method = "start" pointcut-ref = "myPoint" ></ aop:before > < aop:after-returning method = "stop" pointcut-ref = "myPoint" returning = "result" ></ aop:after-returning > < aop:after-throwing method = "logException" pointcut-ref = "myPoint" throwing = "e" ></ aop:after-throwing > </ aop:aspect > </ aop:config > < aop:aspectj-autoproxy ></ aop:aspectj-autoproxy > </ beans > |
2. debug过程
生成的源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | public class MyCalculator$$EnhancerBySpringCGLIB$$3f411fc extends MyCalculator implements SpringProxy, Advised, Factory { private boolean CGLIB$BOUND; public static Object CGLIB$FACTORY_DATA; private static final ThreadLocal CGLIB$THREAD_CALLBACKS; private static final Callback[] CGLIB$STATIC_CALLBACKS; private MethodInterceptor CGLIB$CALLBACK_0; private MethodInterceptor CGLIB$CALLBACK_1; private NoOp CGLIB$CALLBACK_2; private Dispatcher CGLIB$CALLBACK_3; private Dispatcher CGLIB$CALLBACK_4; private MethodInterceptor CGLIB$CALLBACK_5; private MethodInterceptor CGLIB$CALLBACK_6; private static Object CGLIB$CALLBACK_FILTER; private static final Method CGLIB$add$ 0 $Method; private static final MethodProxy CGLIB$add$ 0 $Proxy; private static final Object[] CGLIB$emptyArgs; private static final Method CGLIB$toString$ 1 $Method; private static final MethodProxy CGLIB$toString$ 1 $Proxy; private static final Method CGLIB$sub$ 2 $Method; private static final MethodProxy CGLIB$sub$ 2 $Proxy; private static final Method CGLIB$mul$ 3 $Method; private static final MethodProxy CGLIB$mul$ 3 $Proxy; private static final Method CGLIB$show$ 4 $Method; private static final MethodProxy CGLIB$show$ 4 $Proxy; private static final Method CGLIB$div$ 5 $Method; private static final MethodProxy CGLIB$div$ 5 $Proxy; private static final Method CGLIB$equals$ 6 $Method; private static final MethodProxy CGLIB$equals$ 6 $Proxy; private static final Method CGLIB$hashCode$ 7 $Method; private static final MethodProxy CGLIB$hashCode$ 7 $Proxy; private static final Method CGLIB$clone$ 8 $Method; private static final MethodProxy CGLIB$clone$ 8 $Proxy; static void CGLIB$STATICHOOK1() { CGLIB$THREAD_CALLBACKS = new ThreadLocal(); CGLIB$emptyArgs = new Object[ 0 ]; Class var0 = Class.forName( "org.geekbang.thinking.in.spring.ioc.overview.aop.xml.service.MyCalculator$$EnhancerBySpringCGLIB$$3f411fc" ); Class var1; Method[] var10000 = ReflectUtils.findMethods( new String[]{ "equals" , "(Ljava/lang/Object;)Z" , "hashCode" , "()I" , "clone" , "()Ljava/lang/Object;" }, (var1 = Class.forName( "java.lang.Object" )).getDeclaredMethods()); CGLIB$equals$ 6 $Method = var10000[ 0 ]; CGLIB$equals$ 6 $Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z" , "equals" , "CGLIB$equals$6" ); CGLIB$hashCode$ 7 $Method = var10000[ 1 ]; CGLIB$hashCode$ 7 $Proxy = MethodProxy.create(var1, var0, "()I" , "hashCode" , "CGLIB$hashCode$7" ); CGLIB$clone$ 8 $Method = var10000[ 2 ]; CGLIB$clone$ 8 $Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;" , "clone" , "CGLIB$clone$8" ); var10000 = ReflectUtils.findMethods( new String[]{ "add" , "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;" , "toString" , "()Ljava/lang/String;" , "sub" , "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;" , "mul" , "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;" , "show" , "(Ljava/lang/Integer;)Ljava/lang/Integer;" , "div" , "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;" }, (var1 = Class.forName( "org.geekbang.thinking.in.spring.ioc.overview.aop.xml.service.MyCalculator" )).getDeclaredMethods()); CGLIB$add$ 0 $Method = var10000[ 0 ]; CGLIB$add$ 0 $Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;" , "add" , "CGLIB$add$0" ); CGLIB$toString$ 1 $Method = var10000[ 1 ]; CGLIB$toString$ 1 $Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;" , "toString" , "CGLIB$toString$1" ); CGLIB$sub$ 2 $Method = var10000[ 2 ]; CGLIB$sub$ 2 $Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;" , "sub" , "CGLIB$sub$2" ); CGLIB$mul$ 3 $Method = var10000[ 3 ]; CGLIB$mul$ 3 $Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;" , "mul" , "CGLIB$mul$3" ); CGLIB$show$ 4 $Method = var10000[ 4 ]; CGLIB$show$ 4 $Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Integer;)Ljava/lang/Integer;" , "show" , "CGLIB$show$4" ); CGLIB$div$ 5 $Method = var10000[ 5 ]; CGLIB$div$ 5 $Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;" , "div" , "CGLIB$div$5" ); } final Integer CGLIB$add$ 0 (Integer var1, Integer var2) throws NoSuchMethodException { return super .add(var1, var2); } public final Integer add(Integer var1, Integer var2) throws NoSuchMethodException { MethodInterceptor var10000 = this .CGLIB$CALLBACK_0; if (var10000 == null ) { CGLIB$BIND_CALLBACKS( this ); var10000 = this .CGLIB$CALLBACK_0; } // 从这里进入MethodInterceptor的接口 return var10000 != null ? (Integer)var10000.intercept( this , CGLIB$add$ 0 $Method, new Object[]{var1, var2}, CGLIB$add$ 0 $Proxy) : super .add(var1, var2); } } |
CGLIB$CALLBACK_0的advised对象的targetSource有一个普通对象MyCalculate.
获得执行链
进入调用链
进入实际的方法
到此这篇关于SpringAop源码及调用过程概述的文章就介绍到这了,更多相关SpringAop调用过程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
微信公众号搜索 “ 脚本之家 ” ,选择关注
程序猿的那些事、送书等活动等着你
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 reterry123@163.com 进行投诉反馈,一经查实,立即处理!
相关文章
spring aop Pointcut execution规则介绍
这篇文章主要介绍了spring aop Pointcut execution规则,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-11-11Java ES(Elasticsearch) 中的and 和 or 查
Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎,es中match查询中,查询字符串分词后,默认是or或者的关系,这篇文章主要介绍了ES 中的and 和 or 查询,需要的朋友可以参考下2022-11-11application.yaml与bootstrap.yaml的使用
这篇文章主要介绍了application.yaml与bootstrap.yaml的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-08-08
最新评论