`

mybatis 源码分析之初始化

 
阅读更多

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);
    }
  }

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics