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]

Reply via email to