huangxfchn edited a comment on issue #15086:
URL: 
https://github.com/apache/shardingsphere/issues/15086#issuecomment-1066283999


   > @terrymanu Hi~,Brother Liang. My project also uses open-tracing for jdbc, 
it will proxy the **getConnection()** method of **javax.sql.DataSource**, and 
spring 2.x uses cglib proxy by default, but ShardingSphereDataSource is a final 
class. So, if the **ShardingSphereDataSource** is proxied, this exception will 
occur. The similar code like this:
   > 
   > ```
   > @Aspect
   > public class JdbcAspect {
   > 
   >    @Around("execution(java.sql.Connection *.getConnection(..)) && 
target(javax.sql.DataSource)")
   >    public Object getConnection(final ProceedingJoinPoint pjp) throws 
Throwable {
   >        return new TracingConnection(conn);
   >    }
   > 
   > }
   > ```
   
   You can change the proxy of spring to `jdk` proxy, but it is not 
recommended. After all, there is a reason why spring boot uses cglib proxy by 
default. You can refer to the relevant information
   
   In fact, the best way is to disable dynamic proxying for 
`ShardingSphereDataSource`. We can change the beanName of 
ShardingSphereDataSource to `shardingSphereDataSource.ORIGINAL` and mark it as 
the original instance, so that Spring AOP will not proxy 
`ShardingSphereDataSource`. The relevant code of Spring AOP is as follows:
   
   ```
   
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#shouldSkip
   protected boolean shouldSkip(Class<?> beanClass, String beanName) {
        return AutoProxyUtils.isOriginalInstance(beanName, beanClass);
   }
   
   AutoProxyUtils#isOriginalInstance
   static boolean isOriginalInstance(String beanName, Class<?> beanClass) {
        if (!StringUtils.hasLength(beanName) || beanName.length() !=
                        beanClass.getName().length() + 
AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX.length()) {
                return false;
        }
        return (beanName.startsWith(beanClass.getName()) &&
                        
beanName.endsWith(AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX));
   }
   ```
   
   1. **Option 1, declare the `DataSource` defined in 
`ShardingSphereAutoConfiguration.java` as 
`@Bean("shardingSphereDataSource.ORIGINAL")`, `@Bean("dataSource.ORIGINAL")`**
   ```
   public class ShardingSphereAutoConfiguration implements EnvironmentAware {
       @Bean("shardingSphereDataSource.ORIGINAL")
       @Conditional(LocalRulesCondition.class)
       @Autowired(required = false)
       public DataSource shardingSphereDataSource(final 
ObjectProvider<List<RuleConfiguration>> rules, final 
ObjectProvider<ModeConfiguration> modeConfig) throws SQLException {
           //……
       }
   
       @Bean("dataSource.ORIGINAL")
       @ConditionalOnMissingBean(DataSource.class)
       public DataSource dataSource(final ModeConfiguration modeConfig) throws 
SQLException {
           return ShardingSphereDataSourceFactory.createDataSource(schemaName, 
modeConfig);
       }
   }
   ```
   
   3. **Option 2, modify `beanName` through 
`BeanDefinitionRegistryPostProcessor`**, the code is as follows:
   ```
   @Configuration
   public class ShardingSphereRegistryPostProcessor implements 
BeanDefinitionRegistryPostProcessor {
   
       @Override
       public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry 
registry) throws BeansException {
           String className = ShardingSphereDataSource.class.getName();
           String beanName = "shardingSphereDataSource";
           if(registry.containsBeanDefinition(beanName)){
               BeanDefinition shardingSphereDataSource = 
registry.getBeanDefinition(beanName);
               registry.removeBeanDefinition(beanName);
               registry.registerBeanDefinition(className + 
AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX , shardingSphereDataSource);
               return;
           }
       }
   
       @Override
       public void postProcessBeanFactory(ConfigurableListableBeanFactory 
beanFactory) throws BeansException {
       }
   
   }
   ```
   
   Personally, I prefer the official modification of beanName by shardingSphere.


-- 
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