Ricehomesky commented on issue #13221: URL: https://github.com/apache/skywalking/issues/13221#issuecomment-2854170165
As the result of [#581](https://github.com/apache/skywalking/issues/581) and #12858 , Skywalking add an interceptor on method `hasNoUserSuppliedProxyInterfaces` to prevent the proxy type from being incorrectly modified after enhancement by SkyWalking agent. The key code of proxy type's chosen is as follows: [DefaultAopProxyFactory.java](https://github.com/spring-projects/spring-framework/blob/main/spring-aop/src/main/java/org/springframework/aop/framework/DefaultAopProxyFactory.java) ``` public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface()) { return new JdkDynamicAopProxy(config); } return CglibProxyFactory.createCglibProxy(config); } else { return new JdkDynamicAopProxy(config); } } private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) { Class<?>[] ifcs = config.getProxiedInterfaces(); return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0]))); } ``` However, the second condition that determines the proxy type in the `createAopProxy` method, `config.isProxyTargetClass()` could also be modified. As the following code: [ProxyProcessorSupport.java](https://github.com/spring-projects/spring-framework/blob/main/spring-aop/src/main/java/org/springframework/aop/framework/ProxyProcessorSupport.java) ``` protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) { Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader()); boolean hasReasonableProxyInterface = false; // including skywalking's EnhancedInstance for (Class<?> ifc : targetInterfaces) { if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) && ifc.getMethods().length > 0) { hasReasonableProxyInterface = true; break; } } if (hasReasonableProxyInterface) { // Must allow for introductions; can't just set interfaces to the target's interfaces only. for (Class<?> ifc : targetInterfaces) { proxyFactory.addInterface(ifc); } } else { // cannot be set to true when the beanClass implement EnhancedInstance proxyFactory.setProxyTargetClass(true); } } ``` Spring iterates all of the interfaces implemented by the given beanClass, including `org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance`, The filed `proxyTargetClass` would not be set to true, which affects the proxy type returned by `createAopProxy`. Maybe we could add a new condition just like `isConfigurationCallbackInterface` and `isInternalLanguageInterface` to filter out skywalkking's interface. [ProxyProcessorSupport.java](https://github.com/spring-projects/spring-framework/blob/main/spring-aop/src/main/java/org/springframework/aop/framework/ProxyProcessorSupport.java) ``` protected boolean isConfigurationCallbackInterface(Class<?> ifc) { return (InitializingBean.class == ifc || DisposableBean.class == ifc || Closeable.class == ifc || AutoCloseable.class == ifc || ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class)); } protected boolean isInternalLanguageInterface(Class<?> ifc) { return (ifc.getName().equals("groovy.lang.GroovyObject") || ifc.getName().endsWith(".cglib.proxy.Factory") || ifc.getName().endsWith(".bytebuddy.MockAccess")); } ``` In addition, [ProxyProcessorSupport.java](https://github.com/spring-projects/spring-framework/blob/main/spring-aop/src/main/java/org/springframework/aop/framework/ProxyProcessorSupport.java) added after Spring 4.1.x, we need to investigate the earlier version's situation. -- 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. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
