A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 项老师 黑马粉丝团   /  2018-8-30 10:13  /  1883 人查看  /  14 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

【合肥中心】MyBatis中工厂模式的使用
在MyBatis中获取DataSource时,我们将DataSource相关的数据封装到MyBatis的配置文件中,MyBatis在初始化时,会去读取配置文件中的信息。Mybatis会根据用户的在配置文件的配置,动态的生成DataSource。生成Datasource的过程就使用了工厂模式。我们来看一下源码:
首先:有一个对工厂的抽象接口类
[AppleScript] 纯文本查看 复制代码
public interface DataSourceFactory {
  void setProperties(Properties props);
  DataSource getDataSource();
}

其次,根据不同类型的DataSource,建立不同的DataSourceFactory 3030.png
最后:

通过不同的配置生成不同的DataSourceFactory,从而通过不同的DataSourceFactory建立不同类型的DataSource

[AppleScript] 纯文本查看 复制代码
rivate void environmentsElement(XNode context) throws Exception {
    if (context != null) {
      if (environment == null) {
        environment = context.getStringAttribute("default");
      }
      for (XNode child : context.getChildren()) {
        String id = child.getStringAttribute("id");
        if (isSpecifiedEnvironment(id)) {
          TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));
          DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));
          DataSource dataSource = dsFactory.getDataSource();
          Environment.Builder environmentBuilder = new Environment.Builder(id)
              .transactionFactory(txFactory)
              .dataSource(dataSource);
          configuration.setEnvironment(environmentBuilder.build());
        }
      }
    }
  }

看到这里工厂模式就结束了,对源码的分析一定要定焦。就是我想知道哪个部分是如何实现的,我就关心这一部分。这样才能高效的读懂源码,而不被源码拐偏。如果有好奇的小伙伴,我们顺路来分析一波

[AppleScript] 纯文本查看 复制代码
dataSourceElement

方法的实现:源码如下:

[AppleScript] 纯文本查看 复制代码
  private DataSourceFactory dataSourceElement(XNode context) throws Exception {
    if (context != null) {
      String type = context.getStringAttribute("type");  // 读取XML中type的标签
      Properties props = context.getChildrenAsProperties();  // 读取子节点作为配置
       // 根据type新建一个DataSourceFatory的实际例子
      DataSourceFactory factory = (DataSourceFactory) resolveClass(type).newInstance();
      factory.setProperties(props);
      return factory;
    } 
  } 

这时候我们不妨看看xml中Datasource是如何配置的:

[AppleScript] 纯文本查看 复制代码
 <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
  </dataSource>

再跟源码

[AppleScript] 纯文本查看 复制代码
protected Class<?> resolveClass(String alias) {
    if (alias == null) {
      return null;
    }
    try {
      return resolveAlias(alias);
    } catch (Exception e) {
      throw new BuilderException("Error resolving class. Cause: " + e, e);
    }
  }

再往后还有一些细节,最终我们发现,它是从一张别名表,通过别名表里的配置,去加载到相对应得类,而去创建对象的。

[AppleScript] 纯文本查看 复制代码
typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class);
    typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class);
    typeAliasRegistry.registerAlias("UNPOOLED", UnpooledDataSourceFactory.class);





14 个回复

倒序浏览
就业老师这么负责,学员有福了
回复 使用道具 举报
回复 使用道具 举报
回复 使用道具 举报
回复 使用道具 举报
回复 使用道具 举报
回复 使用道具 举报
6666
回复 使用道具 举报
回复 使用道具 举报
回复 使用道具 举报
回复 使用道具 举报
66666
回复 使用道具 举报
66666
回复 使用道具 举报
回复 使用道具 举报
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马