基于阿里DruidDataSource的多数据源管理

  • 数据源配置信息存储在T_M_ORGANIZATION表中。
列名定义
DB_TYPE‘数据库类型’
DB_DRIVER_CLASS ‘数据库连接驱动’
DB_URL‘数据库连接地址’
DB_USERNAME‘数据库用户名’
DB_PASSWORD‘数据库连接密码’
DB_URL_BAK‘数据库备用地址’
DB_URL_TYPE‘数据源连接地址:1:主地址 2:备用地址’
HAS_CREATE_DATASOURCE‘是否创建过数据源 0:否 1:是’

 

------------

 

1.重写dubbo的spring容器启动方法

 

     需要工程的资源目录下重新定义Spring容器加载类 com.alibaba.dubbo.container.Container 文件名不能修改

文本内容:`xfServer=com.st.tks.utils.spring.SpringContainer`

 

SpringContainer

```java

public class SpringContainer implements Container {

    private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(SpringContainer.class.getName());

    public static final String SPRING_CONFIG = "dubbo.spring.config";

    public static final String DEFAULT_SPRING_CONFIG = "classpath*:META-INF/spring/*.xml";

    static ClassPathXmlApplicationContext context;

 

    public SpringContainer() {

    }

 

    public static ClassPathXmlApplicationContext getContext() {

        return context;

    }

 

    public void start() {

        logger.info("开始启动Spring容器............................................");

        String configPath = ConfigUtils.getProperty("dubbo.spring.config");

        if (configPath == null || configPath.length() == 0) {

            configPath = "classpath*:META-INF/spring/*.xml";

        }

 

        context = new ClassPathXmlApplicationContext(configPath.split("[,\\s]+"));

 

        OrganizationService organizationService = (OrganizationService) context.getBean("organizationService");

        OrganizationDTO dto = new OrganizationDTO();

        List<OrganizationDTO> list = organizationService.selectOrganizationList(dto);

        DruidDataSource baseDateSource = (DruidDataSource) context.getBean("dataSourceBase");//从加载器中获取基础数据源配置类

        DynamicDataSource dataSource = (DynamicDataSource) context.getBean("dataSource");//自定义数据源配置信息类,替代XML文件中反复定义多数据源信息

        if (null != list) {

            for (OrganizationDTO org : list) {

                if (org.getHasCreateDatasource() == 1) {//过滤掉未创建数据源的机构

                    DruidDataSource druidDataSource = null;

                    try {

                        //复制基础数据源中基本配置信息,如:initialSize、minIdle、maxActive

                        druidDataSource = (DruidDataSource) baseDateSource.clone();

                        druidDataSource.setUsername(org.getDbUsername());//设置数据库用户名

                        druidDataSource.setPassword(org.getDbPassword());//设置数据库密码

                        druidDataSource.setUrl(org.getDbUrlType() == 1 ? org.getDbUrl() : org.getDbUrlBak());//使用备用还是主用地址

                    } catch (CloneNotSupportedException e) {

                        e.printStackTrace();

                    }

                    dataSource.addTargetDataSources(org.getOrgSed(), druidDataSource);

                }

 

            }

 

 

        }

        context.start();

    }

 

    public void stop() {

        try {

            if (context != null) {

                logger.info("销毁Spring容器............................................");

                context.stop();

                context.close();

                context = null;

            }

        } catch (Throwable var2) {

            logger.error(var2.getMessage(), var2);

        }

 

    }

}

```

DynamicDataSource

```java

public class DynamicDataSource extends AbstractRoutingDataSource {

    private static org.slf4j.Logger logger = LoggerFactory.getLogger(DynamicDataSource.class.getName());

 

 

    private static Map<Object, Object> targetDataSources;

 

    static {

        targetDataSources = new LinkedHashMap<>();

    }

 

    @Override

    protected Object determineCurrentLookupKey() {

 

        return HandleDataSource.getDataSource();

    }

 

    @Override

    public void setDataSourceLookup(DataSourceLookup dataSourceLookup) {

        super.setDataSourceLookup(dataSourceLookup);

    }

 

    @Override

    public void setDefaultTargetDataSource(Object defaultTargetDataSource) {

        super.setDefaultTargetDataSource(defaultTargetDataSource);

    }

 

    @Override

    public void setTargetDataSources(Map targetDataSources) {

        super.setTargetDataSources(targetDataSources);

        //重点

        super.afterPropertiesSet();

    }

 

    public void addTargetDataSources(String orgSeq, Object dataSource) {

        if (StringUtils.hasText(orgSeq)

                && null != dataSource) {

            logger.info("----------------新增" + orgSeq + "数据连接---------------------:" + orgSeq);

            if (targetDataSources.containsKey(orgSeq)) {

                DruidDataSource db = (DruidDataSource) targetDataSources.get(orgSeq);

                logger.info(orgSeq + " 关闭前的连接数:" + db.getActiveCount() + "--" + db.getConnectCount());

                db.close();//安全关闭数据库连接

                logger.info(orgSeq + " 关闭后的连接数:" + db.getActiveCount() + "--" + db.getConnectCount());

            }

            targetDataSources.put(orgSeq, dataSource);

            setTargetDataSources(targetDataSources);

        }

    }

}

```

 

页面点击刷新数据源动作是,JMS topic分发到各个子业务系统;子业务系统JMS Listener 到刷新动作,刷新数据源信息;

```java

@Override

    public void onMessage(Message message) {

        if (message instanceof TextMessage) {

            TextMessage textMessage = (TextMessage) message;

            try {

                try {

                    ClassPathXmlApplicationContext context = SpringContainer.getContext();

                    OrganizationDTO dto = organizationService.selectOrganizationOne(textMessage.getText());

                    DruidDataSource baseDateSource = (DruidDataSource) context.getBean("dataSourceBase");

                    DynamicDataSource dataSource = (DynamicDataSource) context.getBean("dataSource");

                    logger.info("dataSourceTopic监听刷新数据源" + dto.getOrgSed() + " 线程名:"+Thread.currentThread().getName());

                    if (null != dto) {

                        DruidDataSource druidDataSource = null;

                        try {

                            druidDataSource = (DruidDataSource) baseDateSource.clone();

                            druidDataSource.setUsername(dto.getDbUsername());

                            druidDataSource.setPassword(dto.getDbPassword());

                            druidDataSource.setUrl(dto.getDbUrlType() == 1 ? dto.getDbUrl() : dto.getDbUrlBak());

                            dataSource.addTargetDataSources(dto.getOrgSed(), druidDataSource);

                        } catch (CloneNotSupportedException e) {

                            e.printStackTrace();

                        }

                    }

 

 

                } catch (Exception e) {

                    e.printStackTrace();

                    logger.info("jsm监听消息发生异常");

                }

            } catch (Exception e) {

                e.printStackTrace();

                logger.info("jsm监听消息发生异常");

            }

        }

    }

```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值