998yty 发表于 2016-10-31 10:12:56

Mybatis的Environment解析详解

今天来具体看一下如何解析environments
//XMLConfigBuilder



    private void parseConfiguration(XNode root)

      {

            try

            {

                propertiesElement(root.evalNode("properties"));

                typeAliasesElement(root.evalNode("typeAliases"));

                pluginElement(root.evalNode("plugins"));

                objectFactoryElement(root.evalNode("objectFactory"));

                objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));

                settingsElement(root.evalNode("settings"));

            //解析environments

                environmentsElement(root.evalNode("environments"));

                databaseIdProviderElement(root.evalNode("databaseIdProvider"));

                typeHandlerElement(root.evalNode("typeHandlers"));

                mapperElement(root.evalNode("mappers"));

            }

            catch(Exception e)

            {

                throw new BuilderException((new StringBuilder()).append("Error parsing SQL Mapper Configuration. Cause: ").append(e).toString(), e);

            }

      }

    //解析environments

    private void environmentsElement(XNode context)

            throws Exception

      {

            if(context != null)

            {

                if(C == null)

                  environment = context.getStringAttribute("default");

                Iterator i$ = context.getChildren().iterator();

            //遍历environments的child节点environment,并解析

                do

                {

                  if(!i$.hasNext())

                        break;

                  XNode child = (XNode)i$.next();

                  String id = child.getStringAttribute("id");

            //如果environment的id属性,与environments的default相同时,才解析

                  if(isSpecifiedEnvironment(id))

                  {

                //解析transactionManager

                        TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));

                        //解析dataSource

                DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));

                        javax.sql.DataSource dataSource = dsFactory.getDataSource();

                        org.apache.ibatis.mapping.Environment.Builder environmentBuilder = (new org.apache.ibatis.mapping.Environment.Builder(id)).transactionFactory(txFactory).dataSource(dataSource);

                        configuration.setEnvironment(environmentBuilder.build());

                  }

                } while(true);

            }

      }


//解析transactionManager
先看configuration的构造,启动有JDBC,POOLED类型的映射关系,这个在解析environment节点时,需要用到下载



    typeAliasRegistry.registerAlias("JDBC", org/apache/ibatis/transaction/jdbc/JdbcTransactionFactory);

    typeAliasRegistry.registerAlias("POOLED", org/apache/ibatis/datasource/pooled/PooledDataSourceFactory);





    public Configuration()

      {

            safeRowBoundsEnabled = false;

            safeResultHandlerEnabled = true;

            mapUnderscoreToCamelCase = false;

            aggressiveLazyLoading = true;

            multipleResultSetsEnabled = true;

            useGeneratedKeys = false;//允许JDBC支持生成的键

            useColumnLabel = true;

            cacheEnabled = true;//全局的映射器启用或禁用缓存

            callSettersOnNulls = false;

            localCacheScope = LocalCacheScope.SESSION;//本地一级缓存作用域

            jdbcTypeForNull = JdbcType.OTHER;

            lazyLoadTriggerMethods = new HashSet(Arrays.asList(new String[] {

                "equals", "clone", "hashCode", "toString"

            }));

            defaultExecutorType = ExecutorType.SIMPLE;

            autoMappingBehavior = AutoMappingBehavior.PARTIAL;

            variables = new Properties();

            objectFactory = new DefaultObjectFactory();//默认ObjectFactory

            objectWrapperFactory = new DefaultObjectWrapperFactory();//默认DefaultObjectWrapperFactory

            mapperRegistry = new MapperRegistry(this);

            lazyLoadingEnabled = false;

            interceptorChain = new InterceptorChain();//插件链

            typeHandlerRegistry = new TypeHandlerRegistry();//类型处理注册器

            typeAliasRegistry = new TypeAliasRegistry();//类型别名注册器

            languageRegistry = new LanguageDriverRegistry();

      //mappedStatements Map

            mappedStatements = new StrictMap("Mapped Statements collection");

      //mappedStatements,method,二级缓存

            caches = new StrictMap("Caches collection");

      //MapperInterface 方法返回结果类型Map

            resultMaps = new StrictMap("Result Maps collection");

            //MapperInterface 方法参数类型Map

            parameterMaps = new StrictMap("Parameter Maps collection");

      //主键生成器Map

            keyGenerators = new StrictMap("Key Generators collection");

            loadedResources = new HashSet();

      //Mapper.xml 中statement片段

            sqlFragments = new StrictMap("XML fragments parsed from previous mappers");

      //未解析处理的statements

            incompleteStatements = new LinkedList();

      //未解析处理的CacheRefs

            incompleteCacheRefs = new LinkedList();

      //未解析处理的ResultMaps

            incompleteResultMaps = new LinkedList();

      //未解析处理的Methods

            incompleteMethods = new LinkedList();

            cacheRefMap = new HashMap();

            typeAliasRegistry.registerAlias("JDBC", org/apache/ibatis/transaction/jdbc/JdbcTransactionFactory);

            typeAliasRegistry.registerAlias("MANAGED", org/apache/ibatis/transaction/managed/ManagedTransactionFactory);

            typeAliasRegistry.registerAlias("JNDI", org/apache/ibatis/datasource/jndi/JndiDataSourceFactory);

            typeAliasRegistry.registerAlias("POOLED", org/apache/ibatis/datasource/pooled/PooledDataSourceFactory);

            typeAliasRegistry.registerAlias("UNPOOLED", org/apache/ibatis/datasource/unpooled/UnpooledDataSourceFactory);

            typeAliasRegistry.registerAlias("PERPETUAL", org/apache/ibatis/cache/impl/PerpetualCache);

            typeAliasRegistry.registerAlias("FIFO", org/apache/ibatis/cache/decorators/FifoCache);

            typeAliasRegistry.registerAlias("LRU", org/apache/ibatis/cache/decorators/LruCache);

            typeAliasRegistry.registerAlias("SOFT", org/apache/ibatis/cache/decorators/SoftCache);

            typeAliasRegistry.registerAlias("WEAK", org/apache/ibatis/cache/decorators/WeakCache);

            typeAliasRegistry.registerAlias("VENDOR", org/apache/ibatis/mapping/VendorDatabaseIdProvider);

            typeAliasRegistry.registerAlias("XML", org/apache/ibatis/scripting/xmltags/XMLLanguageDriver);

            typeAliasRegistry.registerAlias("RAW", org/apache/ibatis/scripting/defaults/RawLanguageDriver);

            typeAliasRegistry.registerAlias("SLF4J", org/apache/ibatis/logging/slf4j/Slf4jImpl);

            typeAliasRegistry.registerAlias("COMMONS_LOGGING", org/apache/ibatis/logging/commons/JakartaCommonsLoggingImpl);

            typeAliasRegistry.registerAlias("LOG4J", org/apache/ibatis/logging/log4j/Log4jImpl);

            typeAliasRegistry.registerAlias("JDK_LOGGING", org/apache/ibatis/logging/jdk14/Jdk14LoggingImpl);

            typeAliasRegistry.registerAlias("STDOUT_LOGGING", org/apache/ibatis/logging/stdout/StdOutImpl);

            typeAliasRegistry.registerAlias("NO_LOGGING", org/apache/ibatis/logging/nologging/NoLoggingImpl);

            typeAliasRegistry.registerAlias("CGLIB", org/apache/ibatis/executor/loader/CglibProxyFactory);

            typeAliasRegistry.registerAlias("JAVASSIST", org/apache/ibatis/executor/loader/JavassistProxyFactory);

            languageRegistry.setDefaultDriverClass(org/apache/ibatis/scripting/xmltags/XMLLanguageDriver);

            languageRegistry.register(org/apache/ibatis/scripting/defaults/RawLanguageDriver);

      }


从上可以看出JDBC,POOLED类型别名的映射关系如下:
JDBC,JdbcTransactionFactory 下载
POOLED,PooledDataSourceFactory




    <environments default="development">

            <environment id="development">

                <transactionManager type="JDBC" />

                <dataSource type="POOLED">

                  <property name="driver" value="${driver}" />

                  <property name="url" value="${url}" />

                  <property name="username" value="${username}" />

                  <property name="password" value="${password}" />

                </dataSource>

            </environment>

    </environments>





    private TransactionFactory transactionManagerElement(XNode context)

            throws Exception

      {

            if(context != null)

            {

                String type = context.getStringAttribute("type");

                Properties props = context.getChildrenAsProperties();

            //从类型解决器中,获取type对应的类型的实例,从上面的配置来看

            //实际为JdbcTransactionFactory

                TransactionFactory factory = (TransactionFactory)resolveClass(type).newInstance();

            //设置JdbcTransactionFactory属性

                factory.setProperties(props);

                return factory;

            } else

            {

                throw new BuilderException("Environment declaration requires a TransactionFactory.");

            }

      }



//JdbcTransactionFactory

Java代码下载

    public class JdbcTransactionFactory

      implements TransactionFactory

    {

      public void setProperties(Properties properties)

      {

      }

       //根据数据连接新建事务

      public Transaction newTransaction(Connection conn)

      {

            return new JdbcTransaction(conn);

      }

      //根据数据源和事务级别和是否自动提交,新建事务

      public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit)

      {

            return new JdbcTransaction(ds, level, autoCommit);

      }

    }



//TransactionFactory



    public interface TransactionFactory

    {

      public abstract void setProperties(Properties properties);

      public abstract Transaction newTransaction(Connection connection);

      public abstract Transaction newTransaction(DataSource datasource, TransactionIsolationLevel transactionisolationlevel, boolean flag);

    }


现在来看一下jdbc事务

Java代码下载

    public class JdbcTransaction

      implements Transaction

    {

      private static final Log log = LogFactory.getLog(org/apache/ibatis/transaction/jdbc/JdbcTransaction);

      protected Connection connection;//数据库连接

      protected DataSource dataSource;//数据源

      protected TransactionIsolationLevel level;//事务级别

      protected boolean autoCommmit;//自动提交属性

      

      public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit)

      {

            dataSource = ds;

            level = desiredLevel;

            autoCommmit = desiredAutoCommit;

      }

      

      public JdbcTransaction(Connection connection)

      {

            this.connection = connection;

      }

      

      public Connection getConnection()

            throws SQLException

      {

            if(connection == null)

                openConnection();

            return connection;

      }

      

      public void commit()

            throws SQLException

      {

            if(connection != null && !connection.getAutoCommit())

            {

                if(log.isDebugEnabled())

                  log.debug((new StringBuilder()).append("Committing JDBC Connection [").append(connection).append("]").toString());

                connection.commit();

            }

      }

      

      public void rollback()

            throws SQLException

      {

            if(connection != null && !connection.getAutoCommit())

            {

                if(log.isDebugEnabled())

                  log.debug((new StringBuilder()).append("Rolling back JDBC Connection [").append(connection).append("]").toString());

                connection.rollback();

            }

      }

      

      public void close()

            throws SQLException

      {

            if(connection != null)

            {

                resetAutoCommit();

                if(log.isDebugEnabled())

                  log.debug((new StringBuilder()).append("Closing JDBC Connection [").append(connection).append("]").toString());

                connection.close();

            }

      }

      

      protected void setDesiredAutoCommit(boolean desiredAutoCommit)

      {

            try

            {

                if(connection.getAutoCommit() != desiredAutoCommit)

                {

                  if(log.isDebugEnabled())

                        log.debug((new StringBuilder()).append("Setting autocommit to ").append(desiredAutoCommit).append(" on JDBC Connection [").append(connection).append("]").toString());

                  connection.setAutoCommit(desiredAutoCommit);

                }

            }

            catch(SQLException e)

            {

                throw new TransactionException((new StringBuilder()).append("Error configuring AutoCommit.Your driver may not support getAutoCommit() or setAutoCommit(). Requested setting: ").append(desiredAutoCommit).append(".Cause: ").append(e).toString(), e);

            }

      }

      

      protected void resetAutoCommit()

      {

            try

            {

                if(!connection.getAutoCommit())

                {

                  if(log.isDebugEnabled())

                        log.debug((new StringBuilder()).append("Resetting autocommit to true on JDBC Connection [").append(connection).append("]").toString());

                  connection.setAutoCommit(true);

                }

            }

            catch(SQLException e)

            {

                log.debug((new StringBuilder()).append("Error resetting autocommit to true before closing the connection.Cause: ").append(e).toString());

            }

      }

      //获取connection

      protected void openConnection()

            throws SQLException

      {

            if(log.isDebugEnabled())

                log.debug("Openning JDBC Connection");

            connection = dataSource.getConnection();

            if(level != null)

                connection.setTransactionIsolation(level.getLevel());

            setDesiredAutoCommit(autoCommmit);

      }

    }


//Transaction



    public interface Transaction

    {

      

      public abstract Connection getConnection()

            throws SQLException;

      

      public abstract void commit()

            throws SQLException;

      

      public abstract void rollback()

            throws SQLException;

      

      public abstract void close()

            throws SQLException;

    }


从上面可以看出jdbc对应的事务工厂为JdbcTransactionFactory,由JdbcTransactionFactory,根据数据源,事务级别以及自动提交属性来,创建JdbcTransaction,而JdbcTransaction的事务管理,是通过数据连接connection,而connection是从datasource获取,JdbcTransaction的事务管理,就是依靠相应的数据库driver,来管理,实际依赖于数据库。 下载

//解析dataSource



    private DataSourceFactory dataSourceElement(XNode context)

            throws Exception

      {

            if(context != null)

            {

            //获取数据源的类型,和属性

                String type = context.getStringAttribute("type");

                Properties props = context.getChildrenAsProperties();

            //根据type从configuration的类型处理器,获取具体的DataSourceFactory

            //从上文,我们看一看到type为POOLED,对应的是PooledDataSourceFactory

                DataSourceFactory factory = (DataSourceFactory)resolveClass(type).newInstance();

                factory.setProperties(props);

                return factory;

            } else

            {

                throw new BuilderException("Environment declaration requires a DataSourceFactory.");

            }

      }


// PooledDataSourceFactory



    public class PooledDataSourceFactory extends UnpooledDataSourceFactory

    {

      

      public PooledDataSourceFactory()

      {

            dataSource = new PooledDataSource();

      }

    }

页: [1]
查看完整版本: Mybatis的Environment解析详解