Mybatis的初始化

一.mybatis的初始化。

 //mybaties持久化框架 
 public static void main(String[] args) { 
	  try {
		  //读取配置文件
		InputStream io=Resources.getResourceAsStream("mybatis-config.xml");
		//根据数据流  构建session
		SqlSessionFactory ssf=(new SqlSessionFactoryBuilder()).build(io);
		SqlSession ss=ssf.openSession();
      //根据接口 生成接口的实现类
		UsersMapper  um=ss.getMapper(UsersMapper.class);
		
  	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
 }

1.加载配置文件。

通过Resources.getResourceAsStream("") 加载配置文件,并转换为InputStream对象;底层通过ClassLoader去加载资源。

/**
*  查找具有给定名称的资源
*  java.lang.ClassLoader.getResource(String name) 
                        .findResource(String name)  
* 
*  通过类加载器ClassLoader 去加载资源
*/ 

public URL getResource(String name) {
        URL url;
        if (parent != null) {
            url = parent.getResource(name);
        } else {
            url = getBootstrapResource(name);
        }
        if (url == null) {
            url = findResource(name);
        }
        return url;
    }

2.解析配置文件。

SqlSessionFactory ssf=(new SqlSessionFactoryBuilder()).build(io);
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        inputStream.close();
      } catch (IOException e) {
        // Intentionally ignore. Prefer previous error.
      }
    }
  }

  创建  XMLConfigBuilder对象,在mybatis中全局配置的解析是通过XMLConfigBuilder对象来解析的。具体解析在parse()方法中。

  XMLConfigBuilder继承BaseBuilder

 private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
    //实例化过程中 会创建Configration对象 Configration对象是全局配置类
    //然后调用父类构造方法
    super(new Configuration());
    ErrorContext.instance().resource("SQL Mapper Configuration");
    this.configuration.setVariables(props);
    this.parsed = false;
    this.environment = environment;
    this.parser = parser;
  }

/**
 *Configration对象的构造方法 会把类的别名和类的Class进行注册
 *TypeAliasRegistry类中维护了一个map
 *(这里先说一句)  配置文件中的别名都会在注册容器中去拿.class
 * 如: 在配置中如果使用的JDBC的事务管理 在解析过程中就会从注册容器中拿到对应的
 * 的JdbcTransactionFactory.class 然后去进行实例化 注入到Configration对象中
*/
public Configuration() {
    typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
    typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);

    typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class);
    typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class);
    typeAliasRegistry.registerAlias("UNPOOLED", UnpooledDataSourceFactory.class);

    typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class);
    typeAliasRegistry.registerAlias("FIFO", FifoCache.class);
    typeAliasRegistry.registerAlias("LRU", LruCache.class);
    typeAliasRegistry.registerAlias("SOFT", SoftCache.class);
    typeAliasRegistry.registerAlias("WEAK", WeakCache.class);

    typeAliasRegistry.registerAlias("DB_VENDOR", VendorDatabaseIdProvider.class);

    typeAliasRegistry.registerAlias("XML", XMLLanguageDriver.class);
    typeAliasRegistry.registerAlias("RAW", RawLanguageDriver.class);

    typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class);
    typeAliasRegistry.registerAlias("COMMONS_LOGGING", JakartaCommonsLoggingImpl.class);
    typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class);
    typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class);
    typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class);
    typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class);
    typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class);

    typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class);
    typeAliasRegistry.registerAlias("JAVASSIST", JavassistProxyFactory.class);

    languageRegistry.setDefaultDriverClass(XMLLanguageDriver.class);
    languageRegistry.register(RawLanguageDriver.class);
  }

调用super() 把新创建的Configration对象维护在BeseBuilder中 

 public BaseBuilder(Configuration configuration) {
    this.configuration = configuration;
    this.typeAliasRegistry = this.configuration.getTypeAliasRegistry();
    this.typeHandlerRegistry = this.configuration.getTypeHandlerRegistry();
  }

XMLConfigBuilder解析配置文件  调用parse().解析完标签,封装成对应的对象注入的configration对象中。

 public Configuration parse() {
    if (parsed) {
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
  }

  private void parseConfiguration(XNode root) {
    try {
      //issue #117 read properties first
      propertiesElement(root.evalNode("properties"));
      Properties settings = settingsAsProperties(root.evalNode("settings"));
      loadCustomVfs(settings);
      typeAliasesElement(root.evalNode("typeAliases"));
      pluginElement(root.evalNode("plugins"));
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      reflectorFactoryElement(root.evalNode("reflectorFactory"));
      settingsElement(settings);
      // read it after objectFactory and objectWrapperFactory issue #631
      environmentsElement(root.evalNode("environments"));
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
      typeHandlerElement(root.evalNode("typeHandlers"));
      mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
  }

XMLMapperBuilder解析Mapper.xml

XMLStatementBuilder解析mapper.xml中的select|insert|update|delete标签 MapperStatement对象。

mybatis的初始化,其实就是把配置文件解析成configuration对象的过程,所有的配置信息都维护在Configuration中。 

写到这里不想写了。下次再详细补充吧。

 

你可能感兴趣的:(Mybatis的初始化)