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