001/** 002 * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.mybatisflex.core.mybatis; 017 018import com.mybatisflex.annotation.UseDataSource; 019import com.mybatisflex.core.FlexGlobalConfig; 020import com.mybatisflex.core.datasource.DataSourceKey; 021import com.mybatisflex.core.datasource.FlexDataSource; 022import com.mybatisflex.core.dialect.DbType; 023import com.mybatisflex.core.dialect.DialectFactory; 024import com.mybatisflex.core.row.RowMapper; 025import com.mybatisflex.core.table.TableInfo; 026import com.mybatisflex.core.table.TableInfoFactory; 027import com.mybatisflex.core.util.StringUtil; 028import org.apache.ibatis.session.Configuration; 029 030import java.lang.reflect.InvocationHandler; 031import java.lang.reflect.Method; 032 033public class MapperInvocationHandler implements InvocationHandler { 034 035 private final Object mapper; 036 private final FlexDataSource dataSource; 037 038 public MapperInvocationHandler(Object mapper, Configuration configuration) { 039 this.mapper = mapper; 040 this.dataSource = (FlexDataSource) configuration.getEnvironment().getDataSource(); 041 } 042 043 044 @Override 045 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 046 boolean clearDsKey = false; 047 boolean clearDbType = false; 048 try { 049 //获取用户动态指定,由用户指定数据源,则应该有用户清除 050 String dataSourceKey = DataSourceKey.get(); 051 052 if (StringUtil.isBlank(dataSourceKey)) { 053 //通过 @UseDataSource 或者 @Table(dataSource) 去获取 054 String configDataSourceKey = getConfigDataSourceKey(method, proxy); 055 if (StringUtil.isNotBlank(configDataSourceKey)) { 056 dataSourceKey = configDataSourceKey; 057 DataSourceKey.use(dataSourceKey); 058 clearDsKey = true; 059 } 060 } 061 062 //优先获取用户自己配置的 dbType 063 DbType dbType = DialectFactory.getHintDbType(); 064 if (dbType == null) { 065 if (dataSourceKey != null) { 066 dbType = dataSource.getDbType(dataSourceKey); 067 } 068 if (dbType == null) { 069 dbType = FlexGlobalConfig.getDefaultConfig().getDbType(); 070 } 071 DialectFactory.setHintDbType(dbType); 072 clearDbType = true; 073 } 074 return method.invoke(mapper, args); 075 } finally { 076 if (clearDbType) { 077 DialectFactory.clearHintDbType(); 078 } 079 if (clearDsKey) { 080 DataSourceKey.clear(); 081 } 082 } 083 } 084 085 086 private static String getConfigDataSourceKey(Method method, Object proxy) { 087 UseDataSource useDataSource = method.getAnnotation(UseDataSource.class); 088 if (useDataSource != null && StringUtil.isNotBlank(useDataSource.value())) { 089 return useDataSource.value(); 090 } 091 092 Class<?>[] interfaces = proxy.getClass().getInterfaces(); 093 if (interfaces[0] != RowMapper.class) { 094 TableInfo tableInfo = TableInfoFactory.ofMapperClass(interfaces[0]); 095 if (tableInfo != null) { 096 String dataSourceKey = tableInfo.getDataSource(); 097 if (StringUtil.isNotBlank(dataSourceKey)) { 098 return dataSourceKey; 099 } 100 } 101 } 102 return null; 103 } 104 105 106}