# dynamic-aop-demo **Repository Path**: ccuts/dynamic-aop-demo ## Basic Information - **Project Name**: dynamic-aop-demo - **Description**: 动态aop:支持不重启项目的情况下,自定义嵌入AOP代码进行热插拔操作 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: dynamic-aop-advice-demo - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2021-09-28 - **Last Updated**: 2021-09-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 动态Aop 可以通过外部配置拦截的方法、待执行的代码,在不重启应用的情况下对拦截方法调试。 使用后可以动态卸载插入的代码。 目前没有区分重载 # 自定义代码规则 自定义编码时调用规则,$0表示this对象 (如果是静态方法$0为null),$1~$N为方法参数 在传递code的时候只需要写括号内的部分 比如 ```java String className = $3.getClass().getName(); String methodName = $1.getName(); System.out.println(className+methodName+"hello") ``` 使用环绕通知时,仅需要添加 "invoke();"(它仅起到了标识的作用),实际的返回操作已经在代码中处理好了,例子: ```java String className = $3.getClass().getName(); String methodName = $1.getName(); invoke(); System.out.println(className+methodName+"hello") ``` 例子3:在使用一些非lang包下的类、方法时需要写成全限定类名的形式调用 ``` org.slf4j.Logger log; try{ log= org.slf4j.LoggerFactory.getLogger(this.getClass()); log.info(\"className:{},append:{}\",$3.getClass().getName(),\"123145151515\"); }finally{ com.boolib.mysql.commons.Result.fail(\"失败\"); log.info(\"finally\"); } ``` # aop参数样例 ```java @Override public void before(Method method, Object[] objects, Object o) throws Throwable { String className = $3.getClass().getName(); String methodName = $1.getName(); } @Override public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable { String className = $4.getClass().getName(); String methodName = $2.getName(); } @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { String className = $1.getThis().getClass().getName(); String methodName = $1.getMethod().getName(); return proceed; } public void afterThrowing(Method method, Object[] args, Object target, Exception ex){ } ``` # PostMan请求加载 aopType: 0表示前置,1表示后置,2表示环绕,3表示异常 adviceBeanName:要插入到Spring中的Advice(aop)对象的名称 method: 表示要拦截的某个类中的方法,类和方法之间用#分隔,目前仅支持一对一。 code: 要插入执行的代码。 ``` url: post localhost:9000/proxy/load body:{ "aopType":0, "adviceBeanName":"beforeAop", "method":"com.boolib.mysql.web.SetController#a", "code":"System.out.println($3.getClass().getName()+\"123145151515\");" } ``` # PostMan请求卸载 请求卸载参数一样,主要起作用的是adviceBeanName和method ,会经历两个步骤:1.卸载掉受影响的类、方法,并重新加载。2.卸载Spring中已加载的 AopAdvice Bean。 ``` url: post localhost:9000/proxy/unload body:{ "aopType":0, "adviceBeanName":"beforeAop", "method":"com.boolib.mysql.web.SetController#a", "code":"System.out.println($3.getClass().getName()+\"123145151515\");" } ```