- 数据源配置信息存储在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监听消息发生异常");
}
}
}
```