Ver Fonte

优化动态数据源,添加默认配置.

zhouhao há 8 anos atrás
pai
commit
ade0a7f2fb

+ 4 - 1
hsweb-web-datasource/src/main/java/org/hsweb/web/datasource/dynamic/DynamicDataSourceAutoConfiguration.java

@@ -19,12 +19,13 @@ package org.hsweb.web.datasource.dynamic;
 import com.atomikos.icatch.jta.UserTransactionImp;
 import com.atomikos.icatch.jta.UserTransactionManager;
 import com.atomikos.jdbc.AtomikosDataSourceBean;
-import org.hsweb.web.core.datasource.DynamicDataSource;
 import org.hsweb.web.core.datasource.DataSourceHolder;
+import org.hsweb.web.core.datasource.DynamicDataSource;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cache.annotation.Cacheable;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
@@ -48,6 +49,8 @@ public class DynamicDataSourceAutoConfiguration {
      */
     @Primary
     @Bean(initMethod = "init", name = "dataSource", destroyMethod = "close")
+    @ConditionalOnMissingBean(DataSource.class)
+    @Cacheable
     public DataSource dataSource() {
         AtomikosDataSourceBean dataSourceBean = new AtomikosDataSourceBean();
         properties.putProperties(dataSourceBean);

+ 68 - 33
hsweb-web-datasource/src/main/java/org/hsweb/web/datasource/dynamic/DynamicDataSourceProperties.java

@@ -26,8 +26,6 @@ import org.springframework.util.ClassUtils;
 import org.springframework.util.StringUtils;
 
 import java.sql.SQLException;
-import java.util.LinkedList;
-import java.util.List;
 import java.util.Properties;
 
 /**
@@ -38,31 +36,26 @@ import java.util.Properties;
 @ConfigurationProperties(prefix = "hsweb.dynamicDatasource")
 public class DynamicDataSourceProperties
         implements BeanClassLoaderAware, InitializingBean {
-    private static final List<String> supportDatasourceType;
-    private String       name           = "core";
-    private DatabaseType type           = null;
-    private String       datasourceName = null;
-    private String       username       = "sa";
-    private String       password       = "";
-    private String       url            = "jdbc:h2:file:./data/h2db;DB_CLOSE_ON_EXIT=FALSE";
-    private String testQuery;
-    private int         loginTimeout            = 0;
-    private int         maxLifetime             = 0;
-    private int         minPoolSize             = 2;
-    private int         maxPoolSize             = 20;
-    private int         borrowConnectionTimeout = 30;
-    private int         reapTimeout             = 0;
-    private int         maxIdleTime             = 60;
-    private int         maintenanceInterval     = 60;
-    private int         defaultIsolationLevel   = -1;
-    private int         transactionTimeout      = 300;
-    private Properties  properties              = null;
-    private ClassLoader classLoader             = null;
-
-    static {
-        supportDatasourceType = new LinkedList<>();
-        supportDatasourceType.add("com.alibaba.druid.pool.xa.DruidXADataSource");
-    }
+    private String                name                    = "core";
+    private DatabaseType          type                    = null;
+    private String                datasourceName          = null;
+    private String                username                = "sa";
+    private String                password                = "";
+    private String                url                     = "jdbc:h2:file:./data/h2db;DB_CLOSE_ON_EXIT=FALSE";
+    private String                testQuery               = null;
+    private int                   loginTimeout            = 0;
+    private int                   maxLifetime             = 0;
+    private int                   minPoolSize             = 3;
+    private int                   maxPoolSize             = 80;
+    private int                   borrowConnectionTimeout = 60;
+    private int                   reapTimeout             = 0;
+    private int                   maxIdleTime             = 60;
+    private int                   maintenanceInterval     = 60;
+    private int                   defaultIsolationLevel   = -1;
+    private int                   transactionTimeout      = 300;
+    private Properties            properties              = null;
+    private ClassLoader           classLoader             = null;
+    private DatasourceTypeSupport datasourceTypeSupport   = null;
 
     public int getTransactionTimeout() {
         return transactionTimeout;
@@ -207,9 +200,6 @@ public class DynamicDataSourceProperties
         if (properties == null) {
             properties = new Properties();
         }
-        properties.put("username", getUsername());
-        properties.put("password", getPassword());
-        properties.put("url", getUrl());
         return properties;
     }
 
@@ -228,13 +218,18 @@ public class DynamicDataSourceProperties
             type = DatabaseType.fromJdbcUrl(getUrl());
         }
         if (!StringUtils.hasText(testQuery)) testQuery = getType().getTestQuery();
+        getProperties().put(datasourceTypeSupport.usernameProperty, getUsername());
+        getProperties().put(datasourceTypeSupport.passwordProperty, getPassword());
+        getProperties().put(datasourceTypeSupport.urlProperty, getUrl());
+        initDefaultProperties();
     }
 
     public String lookupSupportDatasourceName() throws ClassNotFoundException {
-        for (String dsClass : supportDatasourceType) {
+        for (DatasourceTypeSupport support : DatasourceTypeSupport.values()) {
             try {
-                ClassUtils.forName(dsClass, classLoader);
-                return dsClass;
+                ClassUtils.forName(support.className, classLoader);
+                datasourceTypeSupport = support;
+                return support.className;
             } catch (ClassNotFoundException e) {
             }
         }
@@ -265,4 +260,44 @@ public class DynamicDataSourceProperties
         }
     }
 
+    public void initDefaultProperties() {
+        datasourceTypeSupport.putDefaultProperties(getProperties());
+    }
+
+    private enum DatasourceTypeSupport {
+        druid("com.alibaba.druid.pool.xa.DruidXADataSource", "username", "password", "url") {
+            @Override
+            public void putDefaultProperties(Properties properties) {
+                super.putDefaultProperties(properties);
+                properties.putIfAbsent("filters", "stat");
+                properties.putIfAbsent("maxActive", 200);
+                properties.putIfAbsent("initialSize", 3);
+                properties.putIfAbsent("minIdle", 3);
+                properties.putIfAbsent("maxWait", 5000);
+                properties.putIfAbsent("timeBetweenEvictionRunsMillis", 60000);
+                properties.putIfAbsent("minEvictableIdleTimeMillis", 1800000);
+                properties.putIfAbsent("testWhileIdle", true);
+                properties.putIfAbsent("testOnBorrow", false);
+                properties.putIfAbsent("testOnReturn", false);
+                properties.putIfAbsent("poolPreparedStatements", true);
+                properties.putIfAbsent("maxOpenPreparedStatements", 20);
+            }
+        };
+
+        DatasourceTypeSupport(String className, String usernameProperty, String passwordProperty, String urlProperty) {
+            this.className = className;
+            this.usernameProperty = usernameProperty;
+            this.passwordProperty = passwordProperty;
+            this.urlProperty = urlProperty;
+        }
+
+        final String className;
+        final String usernameProperty;
+        final String passwordProperty;
+        final String urlProperty;
+
+        public void putDefaultProperties(Properties properties) {
+
+        }
+    }
 }

+ 6 - 15
hsweb-web-datasource/src/main/java/org/hsweb/web/datasource/dynamic/DynamicDataSourceServiceImpl.java

@@ -18,8 +18,6 @@ package org.hsweb.web.datasource.dynamic;
 
 import com.atomikos.jdbc.AtomikosDataSourceBean;
 import com.atomikos.jdbc.AtomikosSQLException;
-import org.apache.commons.beanutils.BeanUtilsBean;
-import org.apache.commons.beanutils.PropertyUtilsBean;
 import org.hsweb.concurrent.lock.LockFactory;
 import org.hsweb.web.bean.po.datasource.DataSource;
 import org.hsweb.web.core.datasource.DatabaseType;
@@ -30,8 +28,6 @@ import org.hsweb.web.service.datasource.DynamicDataSourceService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.PostConstruct;
@@ -39,9 +35,7 @@ import javax.annotation.PreDestroy;
 import javax.annotation.Resource;
 import java.io.Closeable;
 import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
 import java.util.Map;
-import java.util.Properties;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.locks.ReadWriteLock;
@@ -144,22 +138,18 @@ public class DynamicDataSourceServiceImpl implements DynamicDataSourceService {
         properties.setUrl(dataSource.getUrl());
         properties.setType(DatabaseType.fromJdbcUrl(dataSource.getUrl()));
         properties.setTestQuery(dataSource.getTestSql());
+        Map<String, Object> otherProperties = dataSource.getProperties();
         try {
             properties.afterPropertiesSet();
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
-        Map<String, Object> otherProperties = dataSource.getProperties();
         if (otherProperties != null) {
-            PropertyUtilsBean propertyUtilsBean = BeanUtilsBean.getInstance().getPropertyUtils();
-            otherProperties.forEach((k, v) -> {
-                try {
-                    propertyUtilsBean.setProperty(properties, k, v);
-                } catch (Exception e) {
-                    logger.warn("设置动态数据源配置失败", e);
-                }
-            });
+            properties.getProperties().putAll(otherProperties);
+        } else {
+            properties.initDefaultProperties();
         }
+
         AtomikosDataSourceBean dataSourceBean = new AtomikosDataSourceBean();
         properties.putProperties(dataSourceBean);
         boolean[] success = new boolean[1];
@@ -169,6 +159,7 @@ public class DynamicDataSourceServiceImpl implements DynamicDataSourceService {
                 dataSourceBean.init();
                 success[0] = true;
             } catch (AtomikosSQLException e) {
+                logger.error("创建数据源失败", e);
                 closeDataSource(dataSourceBean);
                 cache.remove(dataSource.getId());
             }