mybatis 的配置文件解析又XMLConfigBuilder的parseConfiguration方法来完成,解析结果都存在Configuration这个类中
private void parseConfiguration(XNode root) {//根节点
try {
//解析别名
typeAliasesElement(root.evalNode("typeAliases"));
//解析插件
pluginElement(root.evalNode("plugins"));
//对象工厂解析
//MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成
objectFactoryElement(root.evalNode("objectFactory"));
//
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
//解析属性
propertiesElement(root.evalNode("properties"));
//解析mybatis参数
settingsElement(root.evalNode("settings"));
//解析环境
environmentsElement(root.evalNode("environments"));
//解析类型处理
typeHandlerElement(root.evalNode("typeHandlers"));
//解析mapper映射文件
mapperElement(root.evalNode("mappers"));
} catch (Exception e) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
}
}
别名解析
private void typeAliasesElement(XNode parent) {
if (parent != null) {
for (XNode child : parent.getChildren()) {
String alias = child.getStringAttribute("alias");
String type = child.getStringAttribute("type");
try {
Class<?> clazz = Resources.classForName(type);
if (alias == null) {
//没有设别名时
typeAliasRegistry.registerAlias(clazz);
} else {
//有设别名
typeAliasRegistry.registerAlias(alias, clazz);
}
} catch (ClassNotFoundException e) {
throw new BuilderException("Error registering typeAlias for '" + alias + "'. Cause: " + e, e);
}
}
}
}
public void registerAlias(Class type) {
String alias = type.getSimpleName();
//从注解上获取
Alias aliasAnnotation = (Alias) type.getAnnotation(Alias.class);
if (aliasAnnotation != null) {
alias = aliasAnnotation.value();
}
registerAlias(alias, type);
}
public void registerAlias(String alias, Class value) {
assert alias != null;
String key = alias.toLowerCase();
if (TYPE_ALIASES.containsKey(key) && !TYPE_ALIASES.get(key).equals(value.getName()) && TYPE_ALIASES.get(alias) != null) {
if (!value.equals(TYPE_ALIASES.get(alias))) {
throw new TypeException("The alias '" + alias + "' is already mapped to the value '" + TYPE_ALIASES.get(alias).getName() + "'.");
}
}
//存入hashMaplim
TYPE_ALIASES.put(key, value);
}
插件解析
private void pluginElement(XNode parent) throws Exception {
if (parent != null) {
for (XNode child : parent.getChildren()) {
String interceptor = child.getStringAttribute("interceptor");
//获取插件属性
Properties properties = child.getChildrenAsProperties();
Interceptor interceptorInstance = (Interceptor) resolveClass(interceptor).newInstance();
interceptorInstance.setProperties(properties);
//加入到configuration类的插件执行链里面,其实就是List
configuration.addInterceptor(interceptorInstance);
}
}
z工厂对象解析
private void objectFactoryElement(XNode context) throws Exception {
if (context != null) {
String type = context.getStringAttribute("type");
Properties properties = context.getChildrenAsProperties();
ObjectFactory factory = (ObjectFactory) resolveClass(type).newInstance();
factory.setProperties(properties);
//替换默认的DefaultObjectFactory工厂
configuration.setObjectFactory(factory);
}
}
解析属性
private void propertiesElement(XNode context) throws Exception {
if (context != null) {
Properties defaults = context.getChildrenAsProperties();
String resource = context.getStringAttribute("resource");
String url = context.getStringAttribute("url");
if (resource != null && url != null) {
throw new BuilderException("The properties element cannot specify both a URL and a resource based property file reference. Please specify one or the other.");
}
if (resource != null) {
defaults.putAll(Resources.getResourceAsProperties(resource));
} else if (url != null) {
defaults.putAll(Resources.getUrlAsProperties(url));
}
Properties vars = configuration.getVariables();
if (vars != null) {
defaults.putAll(vars);
}
parser.setVariables(defaults);
configuration.setVariables(defaults);
}
}
解析mybatis参数
private void settingsElement(XNode context) throws Exception {
if (context != null) {
Properties props = context.getChildrenAsProperties();
// Check that all settings are known to the configuration class
MetaClass metaConfig = MetaClass.forClass(Configuration.class);
for (Object key : props.keySet()) {
//严重参数是否合法
if (!metaConfig.hasSetter(String.valueOf(key))) {
throw new BuilderException("The setting " + key + " is not known. Make sure you spelled it correctly (case sensitive).");
}
}
configuration.setAutoMappingBehavior(AutoMappingBehavior.valueOf(stringValueOf(props.getProperty("autoMappingBehavior"), "PARTIAL")));
configuration.setCacheEnabled(booleanValueOf(props.getProperty("cacheEnabled"), true));
configuration.setLazyLoadingEnabled(booleanValueOf(props.getProperty("lazyLoadingEnabled"), false));
configuration.setAggressiveLazyLoading(booleanValueOf(props.getProperty("aggressiveLazyLoading"), true));
configuration.setMultipleResultSetsEnabled(booleanValueOf(props.getProperty("multipleResultSetsEnabled"), true));
configuration.setUseColumnLabel(booleanValueOf(props.getProperty("useColumnLabel"), true));
configuration.setUseGeneratedKeys(booleanValueOf(props.getProperty("useGeneratedKeys"), false));
configuration.setDefaultExecutorType(ExecutorType.valueOf(stringValueOf(props.getProperty("defaultExecutorType"), "SIMPLE")));
configuration.setDefaultStatementTimeout(integerValueOf(props.getProperty("defaultStatementTimeout"), null));
}
}
环境解析
private 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"));
Environment.Builder environmentBuilder = new Environment.Builder(id)
.transactionFactory(txFactory)
.dataSource(dsFactory.getDataSource());
configuration.setEnvironment(environmentBuilder.build());
}
}
}
}
环境解析
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"));
Environment.Builder environmentBuilder = new Environment.Builder(id)
.transactionFactory(txFactory)
.dataSource(dsFactory.getDataSource());
configuration.setEnvironment(environmentBuilder.build());
}
}
}
}
类型处理器解析
private void typeHandlerElement(XNode parent) throws Exception {
if (parent != null) {
for (XNode child : parent.getChildren()) {
String javaType = child.getStringAttribute("javaType");
String jdbcType = child.getStringAttribute("jdbcType");
String handler = child.getStringAttribute("handler");
Class<?> javaTypeClass = resolveClass(javaType);
TypeHandler typeHandlerInstance = (TypeHandler) resolveClass(handler).newInstance();
//也是解析后放在hashmap里
// private final Map<Class<?>, Map<JdbcType, TypeHandler>> TYPE_HANDLER_MAP = new HashMap<Class<?>, Map<JdbcType, TypeHandler>>();
if (jdbcType == null) {
typeHandlerRegistry.register(javaTypeClass, typeHandlerInstance);
} else {
typeHandlerRegistry.register(javaTypeClass, resolveJdbcType(jdbcType), typeHandlerInstance);
}
}
}
}
mapper映射文件
private void mapperElement(XNode parent) throws Exception {
if (parent != null) {
for (XNode child : parent.getChildren()) {
String resource = child.getStringAttribute("resource");
String url = child.getStringAttribute("url");
InputStream inputStream;
if (resource != null && url == null) {
ErrorContext.instance().resource(resource);
inputStream = Resources.getResourceAsStream(resource);
//构建mapper xml 解析
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
mapperParser.parse();
} else if (url != null && resource == null) {
ErrorContext.instance().resource(url);
inputStream = Resources.getUrlAsStream(url);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments());
mapperParser.parse();
} else {
throw new BuilderException("A mapper element may only specify a url or resource, but not both.");
}
}
}
}
public void parse() {
//判断是否已经解析过
if (!configuration.isResourceLoaded(resource)) {
//获取mapper 跟节点并解析
configurationElement(parser.evalNode("/mapper"));
//表示此resource已经解析
configuration.addLoadedResource(resource);
//根据mapper的配置文件命名空间,查找对应的mapper类
bindMapperForNamespace();
}
parsePendingChacheRefs();
parsePendingStatements();
}
private void configurationElement(XNode context) {
try {
String namespace = context.getStringAttribute("namespace");
builderAssistant.setCurrentNamespace(namespace);
cacheRefElement(context.evalNode("cache-ref"));
cacheElement(context.evalNode("cache"));
parameterMapElement(context.evalNodes("/mapper/parameterMap"));
resultMapElements(context.evalNodes("/mapper/resultMap"));
sqlElement(context.evalNodes("/mapper/sql"));
buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
} catch (Exception e) {
throw new RuntimeException("Error parsing Mapper XML. Cause: " + e, e);
}
}