You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2022/12/24 08:22:58 UTC

[shardingsphere] branch master updated: Refactor ReflectionUtil.getFieldValue (#23073)

This is an automated email from the ASF dual-hosted git repository.

duanzhengqiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new ecd9dfe99dd Refactor ReflectionUtil.getFieldValue (#23073)
ecd9dfe99dd is described below

commit ecd9dfe99ddc7f58585bf5a064e6a5362cdfdec1
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Sat Dec 24 16:22:52 2022 +0800

    Refactor ReflectionUtil.getFieldValue (#23073)
    
    * Refactor ReflectionUtil.getFieldValue
    
    * Refactor ReflectionUtil.getFieldValue
---
 .../pool/creator/DataSourcePoolCreator.java        |  2 +-
 .../pool/creator/DataSourceReflection.java         | 12 ++---
 .../metadata/DataSourcePoolMetaDataReflection.java | 41 ++++----------
 .../infra/util/reflection/ReflectionUtil.java      | 63 +++++++++++++++++++++-
 .../xa/jta/datasource/XATransactionDataSource.java |  6 +--
 5 files changed, 81 insertions(+), 43 deletions(-)

diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/datasource/pool/creator/DataSourcePoolCreator.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/datasource/pool/creator/DataSourcePoolCreator.java
index 1aae1d2d836..d48ef1bb960 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/datasource/pool/creator/DataSourcePoolCreator.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/datasource/pool/creator/DataSourcePoolCreator.java
@@ -139,7 +139,7 @@ public final class DataSourcePoolCreator {
             Map<String, Object> jdbcUrlProps = (Map<String, Object>) customDataSourceProps.getProperties().get(jdbcUrlPropertiesFieldName);
             DataSourcePoolMetaDataReflection dataSourcePoolMetaDataReflection = new DataSourcePoolMetaDataReflection(targetDataSource, poolMetaData.getFieldMetaData());
             for (Entry<String, Object> entry : jdbcUrlProps.entrySet()) {
-                dataSourcePoolMetaDataReflection.getJdbcConnectionProperties().setProperty(entry.getKey(), entry.getValue().toString());
+                dataSourcePoolMetaDataReflection.getJdbcConnectionProperties().ifPresent(optional -> optional.setProperty(entry.getKey(), entry.getValue().toString()));
             }
         }
     }
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/datasource/pool/creator/DataSourceReflection.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/datasource/pool/creator/DataSourceReflection.java
index a491ae60188..c29033291a1 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/datasource/pool/creator/DataSourceReflection.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/datasource/pool/creator/DataSourceReflection.java
@@ -160,18 +160,18 @@ public final class DataSourceReflection {
     public void addDefaultDataSourceProperties() {
         DataSourcePoolMetaDataReflection dataSourcePoolMetaDataReflection = new DataSourcePoolMetaDataReflection(dataSource,
                 DataSourcePoolMetaDataFactory.findInstance(dataSource.getClass().getName()).map(DataSourcePoolMetaData::getFieldMetaData).orElseGet(DefaultDataSourcePoolFieldMetaData::new));
-        String jdbcUrl = dataSourcePoolMetaDataReflection.getJdbcUrl();
-        Properties jdbcConnectionProps = dataSourcePoolMetaDataReflection.getJdbcConnectionProperties();
-        if (null == jdbcUrl || null == jdbcConnectionProps) {
+        Optional<String> jdbcUrl = dataSourcePoolMetaDataReflection.getJdbcUrl();
+        Optional<Properties> jdbcConnectionProps = dataSourcePoolMetaDataReflection.getJdbcConnectionProperties();
+        if (!jdbcUrl.isPresent() || !jdbcConnectionProps.isPresent()) {
             return;
         }
-        DataSourceMetaData dataSourceMetaData = DatabaseTypeEngine.getDatabaseType(jdbcUrl).getDataSourceMetaData(jdbcUrl, null);
+        DataSourceMetaData dataSourceMetaData = DatabaseTypeEngine.getDatabaseType(jdbcUrl.get()).getDataSourceMetaData(jdbcUrl.get(), null);
         Properties queryProps = dataSourceMetaData.getQueryProperties();
         for (Entry<Object, Object> entry : dataSourceMetaData.getDefaultQueryProperties().entrySet()) {
             String defaultPropertyKey = entry.getKey().toString();
             String defaultPropertyValue = entry.getValue().toString();
-            if (!containsDefaultProperty(defaultPropertyKey, jdbcConnectionProps, queryProps)) {
-                jdbcConnectionProps.setProperty(defaultPropertyKey, defaultPropertyValue);
+            if (!containsDefaultProperty(defaultPropertyKey, jdbcConnectionProps.get(), queryProps)) {
+                jdbcConnectionProps.get().setProperty(defaultPropertyKey, defaultPropertyValue);
             }
         }
     }
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/datasource/pool/metadata/DataSourcePoolMetaDataReflection.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/datasource/pool/metadata/DataSourcePoolMetaDataReflection.java
index cb3a4dbd797..2152029161e 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/datasource/pool/metadata/DataSourcePoolMetaDataReflection.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/datasource/pool/metadata/DataSourcePoolMetaDataReflection.java
@@ -18,10 +18,10 @@
 package org.apache.shardingsphere.infra.datasource.pool.metadata;
 
 import lombok.RequiredArgsConstructor;
-import lombok.SneakyThrows;
+import org.apache.shardingsphere.infra.util.reflection.ReflectionUtil;
 
 import javax.sql.DataSource;
-import java.lang.reflect.Field;
+import java.util.Optional;
 import java.util.Properties;
 
 /**
@@ -39,8 +39,8 @@ public final class DataSourcePoolMetaDataReflection {
      *
      * @return JDBC URL
      */
-    public String getJdbcUrl() {
-        return getFieldValue(dataSourcePoolFieldMetaData.getJdbcUrlFieldName());
+    public Optional<String> getJdbcUrl() {
+        return ReflectionUtil.getFieldValue(targetDataSource, dataSourcePoolFieldMetaData.getJdbcUrlFieldName());
     }
     
     /**
@@ -48,8 +48,8 @@ public final class DataSourcePoolMetaDataReflection {
      * 
      * @return username
      */
-    public String getUsername() {
-        return getFieldValue(dataSourcePoolFieldMetaData.getUsernameFieldName());
+    public Optional<String> getUsername() {
+        return ReflectionUtil.getFieldValue(targetDataSource, dataSourcePoolFieldMetaData.getUsernameFieldName());
     }
     
     /**
@@ -57,8 +57,8 @@ public final class DataSourcePoolMetaDataReflection {
      *
      * @return password
      */
-    public String getPassword() {
-        return getFieldValue(dataSourcePoolFieldMetaData.getPasswordFieldName());
+    public Optional<String> getPassword() {
+        return ReflectionUtil.getFieldValue(targetDataSource, dataSourcePoolFieldMetaData.getPasswordFieldName());
     }
     
     /**
@@ -66,28 +66,7 @@ public final class DataSourcePoolMetaDataReflection {
      * 
      * @return JDBC connection properties
      */
-    public Properties getJdbcConnectionProperties() {
-        return getFieldValue(dataSourcePoolFieldMetaData.getJdbcUrlPropertiesFieldName());
-    }
-    
-    @SuppressWarnings("unchecked")
-    @SneakyThrows(ReflectiveOperationException.class)
-    private <T> T getFieldValue(final String fieldName) {
-        Class<?> dataSourceClass = targetDataSource.getClass();
-        Field field = null;
-        boolean isFound = false;
-        while (!isFound) {
-            try {
-                field = dataSourceClass.getDeclaredField(fieldName);
-                isFound = true;
-            } catch (final ReflectiveOperationException ignored) {
-                dataSourceClass = dataSourceClass.getSuperclass();
-                if (Object.class == dataSourceClass) {
-                    return null;
-                }
-            }
-        }
-        field.setAccessible(true);
-        return (T) field.get(targetDataSource);
+    public Optional<Properties> getJdbcConnectionProperties() {
+        return ReflectionUtil.getFieldValue(targetDataSource, dataSourcePoolFieldMetaData.getJdbcUrlPropertiesFieldName());
     }
 }
diff --git a/infra/util/src/main/java/org/apache/shardingsphere/infra/util/reflection/ReflectionUtil.java b/infra/util/src/main/java/org/apache/shardingsphere/infra/util/reflection/ReflectionUtil.java
index f61c4eb32af..17fdea5d40c 100644
--- a/infra/util/src/main/java/org/apache/shardingsphere/infra/util/reflection/ReflectionUtil.java
+++ b/infra/util/src/main/java/org/apache/shardingsphere/infra/util/reflection/ReflectionUtil.java
@@ -22,6 +22,8 @@ import lombok.NoArgsConstructor;
 import lombok.SneakyThrows;
 
 import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Optional;
 
 /**
  * Reflection utility.
@@ -31,6 +33,44 @@ public final class ReflectionUtil {
     
     /**
      * Get field value.
+     * 
+     * @param target target
+     * @param fieldName field name
+     * @param <T> type of field value
+     * @return field value
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> Optional<T> getFieldValue(final Object target, final String fieldName) {
+        return findField(fieldName, target.getClass()).map(optional -> (T) getFieldValue(target, optional));
+    }
+    
+    @SneakyThrows(IllegalAccessException.class)
+    private static Object getFieldValue(final Object target, final Field field) {
+        boolean accessible = field.isAccessible();
+        if (!accessible) {
+            field.setAccessible(true);
+        }
+        Object result = field.get(target);
+        if (!accessible) {
+            field.setAccessible(false);
+        }
+        return result;
+    }
+    
+    private static Optional<Field> findField(final String fieldName, final Class<?> targetClass) {
+        Class<?> currentTargetClass = targetClass;
+        while (Object.class != currentTargetClass) {
+            try {
+                return Optional.of(currentTargetClass.getDeclaredField(fieldName));
+            } catch (final NoSuchFieldException ignored) {
+                currentTargetClass = currentTargetClass.getSuperclass();
+            }
+        }
+        return Optional.empty();
+    }
+    
+    /**
+     * Get static field value.
      *
      * @param target target
      * @param fieldName field name
@@ -51,7 +91,7 @@ public final class ReflectionUtil {
     }
     
     /**
-     * Set field value.
+     * Set static field value.
      * 
      * @param target target
      * @param fieldName field name
@@ -69,4 +109,25 @@ public final class ReflectionUtil {
             field.setAccessible(false);
         }
     }
+    
+    /**
+     * Invoke method.
+     *
+     * @param method method
+     * @param target target
+     * @param args arguments
+     * @return invoke result
+     */
+    @SneakyThrows(ReflectiveOperationException.class)
+    public static Object invokeMethod(final Method method, final Object target, final Object... args) {
+        boolean accessible = method.isAccessible();
+        if (!accessible) {
+            method.setAccessible(true);
+        }
+        Object result = method.invoke(target, args);
+        if (!accessible) {
+            method.setAccessible(false);
+        }
+        return result;
+    }
 }
diff --git a/kernel/transaction/type/xa/core/src/main/java/org/apache/shardingsphere/transaction/xa/jta/datasource/XATransactionDataSource.java b/kernel/transaction/type/xa/core/src/main/java/org/apache/shardingsphere/transaction/xa/jta/datasource/XATransactionDataSource.java
index b232c4ea24a..5ba235238c8 100644
--- a/kernel/transaction/type/xa/core/src/main/java/org/apache/shardingsphere/transaction/xa/jta/datasource/XATransactionDataSource.java
+++ b/kernel/transaction/type/xa/core/src/main/java/org/apache/shardingsphere/transaction/xa/jta/datasource/XATransactionDataSource.java
@@ -18,6 +18,7 @@
 package org.apache.shardingsphere.transaction.xa.jta.datasource;
 
 import org.apache.shardingsphere.infra.database.type.DatabaseType;
+import org.apache.shardingsphere.infra.util.reflection.ReflectionUtil;
 import org.apache.shardingsphere.transaction.xa.jta.connection.XAConnectionWrapperFactory;
 import org.apache.shardingsphere.transaction.xa.spi.SingleXAResource;
 import org.apache.shardingsphere.transaction.xa.spi.XATransactionManagerProvider;
@@ -29,7 +30,6 @@ import javax.transaction.RollbackException;
 import javax.transaction.Synchronization;
 import javax.transaction.SystemException;
 import javax.transaction.Transaction;
-import java.lang.reflect.Method;
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.util.Arrays;
@@ -113,9 +113,7 @@ public final class XATransactionDataSource implements AutoCloseable {
     
     private void close(final DataSource dataSource) {
         try {
-            Method method = dataSource.getClass().getDeclaredMethod("close");
-            method.setAccessible(true);
-            method.invoke(dataSource);
+            ReflectionUtil.invokeMethod(dataSource.getClass().getDeclaredMethod("close"), dataSource);
         } catch (final ReflectiveOperationException ignored) {
         }
     }