stateIs0 edited a comment on issue #6932:
URL: https://github.com/apache/skywalking/issues/6932#issuecomment-839755006


   @wu-sheng 
   First of all, I'm not sure what your solution with ShardingSphere is, but my 
feeling is that it would be better not to introduce other components.
   Then, let me talk briefly about our current solution:
   1. Collect all plug-ins with class as key.
   2. When calling a method, find an interceptor matching the method according 
to method.
   3. Find these interceptors and build a chain of filters. And cache the 
filter chain.
   4. Make a call to the filter chain
   
   The pseudocode is as follows:
   
   ```Java
   @RuntimeType
   public Object trace(@This Object obj,
                           @AllArguments Object[] allArguments,
                           @Origin Method method,
                           @SuperCall Callable<?> zuper) throws Throwable {
           if (cache.get(method) != null) {
               return cache.get(method).invoke(new ParamModel(obj, 
allArguments, method, zuper));
           }
           List<Builder.Interceptor> interceptorList = new ArrayList<>();
           for (Builder.Interceptor interceptor : interceptors) {
               List<ElementMatcher<MethodDescription>> matches = 
interceptor.matches();
               for (ElementMatcher<MethodDescription> match : matches) {
                   // 找到能够匹配这个方法的拦截器.
                   if (match.matches(new 
MethodDescription.ForLoadedMethod(method))) {
                       interceptorList.add(interceptor);
                   }
               }
           }
           // 排序
           
interceptorList.sort(Comparator.comparingInt(Builder.Interceptor::order));
           List<ChainFactory.Filter<Object, ParamModel>> list = new 
ArrayList<>();
           // 将每个拦截器用 filter 包装起来
           for (Builder.Interceptor interceptor : interceptorList) {
               list.add((target, arg) -> {
                   // before
                   interceptor.beforeMethod(arg.obj, arg.method, 
arg.allArguments, method.getParameterTypes(), new MethodInterceptResult());
                   Object result = null;
                   try {
                       // 下个过滤器进行调用
                       result = target.invoke(arg);
                   } catch (Throwable throwable) {
                       interceptor.handleMethodException(arg.obj, arg.method, 
arg.allArguments, method.getParameterTypes(), throwable);
                   }
                   // after
                   interceptor.afterMethod(arg.obj, arg.method, 
arg.allArguments, method.getParameterTypes(), result);
                   return result;
               });
           }
   
           //  构建过滤器链, 并添加尾部节点. 尾部节点直接调用目标方法.
           ChainFactory.Invoker<Object, ParamModel> chain = 
ChainFactory.build(list, paramModel -> paramModel.zuper.call());
   
           // 发起调用.
           Object result = chain.invoke(new ParamModel(obj, allArguments, 
method, zuper));
           return result;
   }
   
   ```
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to