使用Spring的getBeansOfType实现接口多实现类的动态调用,一个接口有一个抽象类实现再有多个实现类继承。

org.springframework.beans及org.springframework.context这两个包是Spring IoC容器的基础,
其中重要的类有BeanFactory,BeanFactory是IoC容器的核心接口,其职责包括:实例化、定位、配置应用程序中的
对象及建立这些对象间的依赖关系。

ApplicationContext作为BeanFactory的子类,在Bean管理的功能上得到了很大的增强,也更易于与Spring AOP集成使用。
今天我们要讨论的并不是BeanFactory或者ApplicationContext的实现原理,而是对ApplicationContext的一种实际应用方式。

在实际工作中,我们经常会遇到一个接口及多个实现类的情况,并且在不同的条件下会使用不同的实现类。我们可以借助ApplicationContext的getBeansOfType来实现我们需要的结果

<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;

问题:执行sql语句,却会有多种数据库,选择相对应的数据库.通过多个数据库类型实现类。

一个接口类:

/**
 * 操作数据库的接口类
 * @author chenp
 */

public interface DbCaller {

    /**
     * 执行sql语句
     * @param chkUpdateScript //sql语句内容类
     * @param chkDatabase  //数据库信息类
     * @return AjaxResult
     */
    AjaxResult executeSqlInvoke(ChkUpdateScript chkUpdateScript, ChkDatabase chkDatabase) throws Exception;
}

通过一个抽象类实现该接口:

/**
 * 操作数据库抽象类
 * @Date 2022-07-11
 */
public abstract class AbstractDbCaller implements DbCaller{

    /**
     * 执行sql语句
     * @param chkUpdateScript
     * @param chkDatabase
     * @return AjaxResult
     */
    @Override
    public AjaxResult executeSqlInvoke(ChkUpdateScript chkUpdateScript, ChkDatabase chkDatabase) throws Exception {
        return executeSql(chkUpdateScript, chkDatabase);
    }

    /**
     * 执行sql语句
     * @param chkUpdateScript
     * @param chkDatabase
     * @return AjaxResult
     */
    protected abstract AjaxResult executeSql(ChkUpdateScript chkUpdateScript, ChkDatabase chkDatabase) throws Exception;
}

再由一个实现类继承该抽象类(mysql实现类):(其中调用了一个加密工具类和一个jdbc工具类用于执行sql语句)

/**
 * mysql数据库执行sql语句
 **/
@Component("MYSQL_CALLER")
public class MysqlCaller extends AbstractDbCaller{

    /**
     * 执行sql语句
     * @param chkUpdateScript
     * @param chkDatabase
     * @return AjaxResult
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    protected AjaxResult  executeSql(ChkUpdateScript chkUpdateScript, ChkDatabase chkDatabase) throws Exception {
        //获取用户名
        String username =chkDatabase.getUsername();
        //获取密码
        String password = EncryptUtil.getInstance().DESdecode(chkDatabase.getPassword());
        //数据库url地址
        String dataSourceUrl = chkDatabase.getDataSourceUrl();
        //获取驱动类
        String databaseTypeDriver = chkDatabase.getDriver();
        //获取sql语句
        String sql = chkUpdateScript.getScriptContent();
        //将sql脚本文件按分号分割开来
        String[] sqlStatement = sql.split(";");
        //获取数据库名称
        String databaseName = chkDatabase.getDatabaseName();
        //uuid
        String uuid = "uuid";
        //执行sql语句
        for (int i = 0; i<sqlStatement.length; i++){
            Boolean aBoolean = JDBCUtils.getInstance().executeSql(databaseTypeDriver, dataSourceUrl, username, password, sqlStatement[i], uuid);
            if(!aBoolean == true){
                String msg = sql + "SQL语句执行失败,执行数据库为" + databaseName;
                return AjaxResult.error(msg);
            }
        }
        String msg = sql + "SQL语句执行成功,执行数据库为" + databaseName;
        return AjaxResult.success(msg);
    }
}

实现类可多写,如再写也该Orcher数据库继承该抽象类

/**
 * mysql数据库执行sql语句
 **/
@Component("Orcher_CALLER")
public class OrcherCaller extends AbstractDbCaller{

    /**
     * 执行sql语句
     * @param chkUpdateScript
     * @param chkDatabase
     * @return AjaxResult
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    protected AjaxResult  executeSql(ChkUpdateScript chkUpdateScript, ChkDatabase chkDatabase) throws Exception {

    }
}

关键在于如何调用不同的实现类,

        也就是通过这个注解@Component("MYSQL_CALLER")来识别不同的bean

调用方法:

//获取数据库类型信息 ===mysql
String databaseType = chkDatabase.getDatabaseType();

 //数据库类型接口   ====MYSQL_CALLER
String  invokeName = databaseType.toUpperCase() + CommonConstant.DATASOURCE_AUTOWIRED_NAME;

//获取相应的bean  ====MYSQL_CALLER
DbCaller dbCaller = SpringUtils.getBean(invokeName);

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值