SqlSessionFactory初始化

mybatis 使用教程: http://donald-draper.iteye.com/blog/2330429
Mybatis加载解析Mapper(xml)文件第一讲: http://donald-draper.iteye.com/blog/2333125
Mybatis加载解析Mapper(xml)文件第二讲: http://donald-draper.iteye.com/blog/2333191
在使用教程,我们有一个静态方法,初始化SqlSessionFactory
static{
        try{
            reader    = Resources.getResourceAsReader("mybatisConfig.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
	    }
    }

这篇文章,主要解决SqlSessionFactory是如何初始化的问题?我们从这一句开始
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader)
public class SqlSessionFactoryBuilder
{
    public SqlSessionFactory build(Reader reader)
    {
        return build(reader, null, null);
    }
    //创建SqlSessionFactory
     public SqlSessionFactory build(Reader reader, String environment, Properties properties)
    {
        SqlSessionFactory sqlsessionfactory;
        try
        {
	    //解析配置文件
            XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
	    //根据Configuration,创建sqlsessionfactory
            sqlsessionfactory = build(parser.parse());
        }
        catch(Exception e)
        {
            throw ExceptionFactory.wrapException("Error building SqlSession.", e);
        }
        ErrorContext.instance().reset();
    }
    //根据Configuration,创建sqlsessionfactory
    public SqlSessionFactory build(Configuration config)
    {
        return new DefaultSqlSessionFactory(config);
    }
}

先看解析配置文件
public class XMLConfigBuilder extends BaseBuilder
{
    private boolean parsed;//解析状态
    private XPathParser parser;
    private String environment;//环境


    public XMLConfigBuilder(Reader reader, String environment, Properties props)
    {
        this(new XPathParser(reader, true, props, new XMLMapperEntityResolver()), environment, props);
    }
    //初始化XMLConfigBuilder
    private XMLConfigBuilder(XPathParser parser, String environment, Properties props)
    {
        super(new Configuration());
        ErrorContext.instance().resource("SQL Mapper Configuration");
        configuration.setVariables(props);
        parsed = false;
        this.environment = environment;
        this.parser = parser;
    }

    //获取配置信息Configuration
     public Configuration parse()
    {
        if(parsed)
        {
            throw new BuilderException("Each MapperConfigParser can only be used once.");
        } else
        {
            parsed = true;
	    //解析mybatisConfig.xml文件
            parseConfiguration(parser.evalNode("/configuration"));
            return configuration;
        }
    }
    //解析mybatisConfig.xml文件,properties,typeAliases,plugins,objectFactory,objectWrapperFactory
    //settings,environments,databaseIdProvider,typeHandlers,mappers
    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"));
            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);
        }
    }
}

//Mybatis配置项
public class Configuration{
    protected Environment environment;//环境
    protected boolean safeRowBoundsEnabled;
    protected boolean safeResultHandlerEnabled;
    protected boolean mapUnderscoreToCamelCase;
    protected boolean aggressiveLazyLoading;
    protected boolean multipleResultSetsEnabled;
    protected boolean useGeneratedKeys;//允许JDBC支持生成的键
    protected boolean useColumnLabel;
    protected boolean cacheEnabled;//全局的映射器启用或禁用缓存
    protected boolean callSettersOnNulls;
    protected String logPrefix;
    protected Class logImpl;
    protected LocalCacheScope localCacheScope;//本地一级缓存作用域
    protected JdbcType jdbcTypeForNull;
    protected Set lazyLoadTriggerMethods;
    protected Integer defaultStatementTimeout;
    protected ExecutorType defaultExecutorType;
    protected AutoMappingBehavior autoMappingBehavior;
    protected Properties variables;
    protected ObjectFactory objectFactory;
    protected ObjectWrapperFactory objectWrapperFactory;
    protected MapperRegistry mapperRegistry;
    protected boolean lazyLoadingEnabled;
    protected ProxyFactory proxyFactory;
    protected String databaseId;
    protected final InterceptorChain interceptorChain;//插件链
    protected final TypeHandlerRegistry typeHandlerRegistry;//类型处理注册器
    protected final TypeAliasRegistry typeAliasRegistry;//类型别名注册器
    protected final LanguageDriverRegistry languageRegistry;
    protected final Map mappedStatements;//
    protected final Map caches;
    protected final Map resultMaps;
    protected final Map parameterMaps;
    protected final Map keyGenerators;
    protected final Set loadedResources;
    protected final Map sqlFragments;
    protected final Collection incompleteStatements;
    protected final Collection incompleteCacheRefs;
    protected final Collection incompleteResultMaps;
    protected final Collection incompleteMethods;
    protected final Map cacheRefMap;
    //初始化配置项
     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();
        objectWrapperFactory = new DefaultObjectWrapperFactory();
        mapperRegistry = new MapperRegistry(this);
        lazyLoadingEnabled = false;
        interceptorChain = new InterceptorChain();//插件链
        typeHandlerRegistry = new TypeHandlerRegistry();//类型处理注册器
        typeAliasRegistry = new TypeAliasRegistry();//类型别名注册器
        languageRegistry = new LanguageDriverRegistry();
        mappedStatements = new StrictMap("Mapped Statements collection");
        caches = new StrictMap("Caches collection");
        resultMaps = new StrictMap("Result Maps collection");
        parameterMaps = new StrictMap("Parameter Maps collection");
        keyGenerators = new StrictMap("Key Generators collection");
        loadedResources = new HashSet();
        sqlFragments = new StrictMap("XML fragments parsed from previous mappers");
        incompleteStatements = new LinkedList();
        incompleteCacheRefs = new LinkedList();
        incompleteResultMaps = new LinkedList();
        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);
    }
    //设置Configuration,属性变量variables
     public void setVariables(Properties variables)
    {
        this.variables = variables;
    }
}


//BaseBuilder
public abstract class BaseBuilder
{

    public BaseBuilder(Configuration configuration)
    {
        this.configuration = configuration;
        typeAliasRegistry = this.configuration.getTypeAliasRegistry();
        typeHandlerRegistry = this.configuration.getTypeHandlerRegistry();
    }
    protected final Configuration configuration;//Mybatis配置项
    protected final TypeAliasRegistry typeAliasRegistry;
    protected final TypeHandlerRegistry typeHandlerRegistry;
}

来看new XPathParser(reader, true, props, new XMLMapperEntityResolver()这一句构造XPathParser
public class XPathParser
{
    private Document document;//文档
    private boolean validation;
    private EntityResolver entityResolver;//实体解决器
    private Properties variables;
    private XPath xpath;
    //构造XPathParser
    public XPathParser(Reader reader, boolean validation, Properties variables, EntityResolver entityResolver)
    {
        commonConstructor(validation, variables, entityResolver);
        document = createDocument(new InputSource(reader));
    }
    //初始化entityResolver,xpath
     private void commonConstructor(boolean validation, Properties variables, EntityResolver entityResolver)
    {
        this.validation = validation;
        this.entityResolver = entityResolver;
        this.variables = variables;
        XPathFactory factory = XPathFactory.newInstance();
        xpath = factory.newXPath();
    }
    //创建Document
     private Document createDocument(InputSource inputSource)
    {
        DocumentBuilder builder;
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setValidating(validation);
        factory.setNamespaceAware(false);
        factory.setIgnoringComments(true);
        factory.setIgnoringElementContentWhitespace(false);
        factory.setCoalescing(false);
        factory.setExpandEntityReferences(true);
        builder = factory.newDocumentBuilder();
        builder.setEntityResolver(entityResolver);
        builder.setErrorHandler(new ErrorHandler() {

            public void error(SAXParseException exception)
                throws SAXException
            {
                throw exception;
            }

            public void fatalError(SAXParseException exception)
                throws SAXException
            {
                throw exception;
            }

            public void warning(SAXParseException saxparseexception)
                throws SAXException
            {
            }

            final XPathParser this$0;

            
            {
                this$0 = XPathParser.this;
                super();
            }
        });
        return builder.parse(inputSource);
        Exception e;
        e;
        throw new BuilderException((new StringBuilder()).append("Error creating document instance.  Cause: ").append(e).toString(), e);
    }
    //根据表达式返回document对应的XNode
    public XNode evalNode(String expression)
    {
        return evalNode(document, expression);
    }
    public XNode evalNode(Object root, String expression)
    {
        Node node = (Node)evaluate(expression, root, XPathConstants.NODE);
        if(node == null)
            return null;
        else
            return new XNode(this, node, variables);
    }
    private Object evaluate(String expression, Object root, QName returnType)
    {
        return xpath.evaluate(expression, root, returnType);
    }
}

//XNode
public class XNode
{
    public XNode(XPathParser xpathParser, Node node, Properties variables)
    {
        this.xpathParser = xpathParser;
        this.node = node;
        name = node.getNodeName();
        this.variables = variables;
        attributes = parseAttributes(node);
        body = parseBody(node);
    }
    private Node node;
    private String name;
    private String body;
    private Properties attributes;
    private Properties variables;
    private XPathParser xpathParser;
}

现在回到XMLConfigBuilder的解析mybatisConfig.xml文件
parseConfiguration(parser.evalNode("/configuration"));
 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"));
            environmentsElement(root.evalNode("environments"));
            databaseIdProviderElement(root.evalNode("databaseIdProvider"));
            typeHandlerElement(root.evalNode("typeHandlers"));
            mapperElement(root.evalNode("mappers"));
        }
    }

下面依次来看properties,typeAliases,plugins,objectFactory,objectWrapperFactory
,settings,environments,databaseIdProvider,typeHandlers,mappers的解析初始化
初始化properties
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);
        }
    }

在XMLConfigBuilder的构造函数中初始化过Variables,首先加载properties标签中
resource为Properties,如果在构造SqlSessionFactoryBuilder
(sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader))
的过程中,传入了Properties文件,
则覆盖掉resource的Properties。
初始化typeAliases
private void typeAliasesElement(XNode parent)
    {
        if(parent != null)
        {
            for(Iterator i$ = parent.getChildren().iterator(); i$.hasNext();)
            {
                XNode child = (XNode)i$.next();
                if("package".equals(child.getName()))
                {
                    String typeAliasPackage = child.getStringAttribute("name");
                    configuration.getTypeAliasRegistry().registerAliases(typeAliasPackage);
                } else
                {
                    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);
                    }                  
                }
            }

        }
    }

//TypeAliasRegistry
public class TypeAliasRegistry
{
    //实际上类型别名是存储在一个Map中
    //HashMap<String,Classs>,key为alias,Class为类Type
    private final HashMap TYPE_ALIASES = new HashMap();
    public TypeAliasRegistry()
    {
        //系统默认类型别名
        registerAlias("string", java/lang/String);
        registerAlias("byte", java/lang/Byte);
        registerAlias("long", java/lang/Long);
        registerAlias("short", java/lang/Short);
        registerAlias("int", java/lang/Integer);
        registerAlias("integer", java/lang/Integer);
        registerAlias("double", java/lang/Double);
        registerAlias("float", java/lang/Float);
        registerAlias("boolean", java/lang/Boolean);
        registerAlias("byte[]", [Ljava/lang/Byte;);
        registerAlias("long[]", [Ljava/lang/Long;);
        registerAlias("short[]", [Ljava/lang/Short;);
        registerAlias("int[]", [Ljava/lang/Integer;);
        registerAlias("integer[]", [Ljava/lang/Integer;);
        registerAlias("double[]", [Ljava/lang/Double;);
        registerAlias("float[]", [Ljava/lang/Float;);
        registerAlias("boolean[]", [Ljava/lang/Boolean;);
        registerAlias("_byte", Byte.TYPE);
        registerAlias("_long", Long.TYPE);
        registerAlias("_short", Short.TYPE);
        registerAlias("_int", Integer.TYPE);
        registerAlias("_integer", Integer.TYPE);
        registerAlias("_double", Double.TYPE);
        registerAlias("_float", Float.TYPE);
        registerAlias("_boolean", Boolean.TYPE);
        registerAlias("_byte[]", [B);
        registerAlias("_long[]", [J);
        registerAlias("_short[]", [S);
        registerAlias("_int[]", [I);
        registerAlias("_integer[]", [I);
        registerAlias("_double[]", [D);
        registerAlias("_float[]", [F);
        registerAlias("_boolean[]", [Z);
        registerAlias("date", java/util/Date);
        registerAlias("decimal", java/math/BigDecimal);
        registerAlias("bigdecimal", java/math/BigDecimal);
        registerAlias("biginteger", java/math/BigInteger);
        registerAlias("object", java/lang/Object);
        registerAlias("date[]", [Ljava/util/Date;);
        registerAlias("decimal[]", [Ljava/math/BigDecimal;);
        registerAlias("bigdecimal[]", [Ljava/math/BigDecimal;);
        registerAlias("biginteger[]", [Ljava/math/BigInteger;);
        registerAlias("object[]", [Ljava/lang/Object;);
        registerAlias("map", java/util/Map);
        registerAlias("hashmap", java/util/HashMap);
        registerAlias("list", java/util/List);
        registerAlias("arraylist", java/util/ArrayList);
        registerAlias("collection", java/util/Collection);
        registerAlias("iterator", java/util/Iterator);
        registerAlias("ResultSet", java/sql/ResultSet);
    }
    //类型别名注册器,注册类型别名
     public void registerAlias(String alias, Class value)
    {
        if(alias == null)
            throw new TypeException("The parameter alias cannot be null");
        String key = alias.toLowerCase(Locale.ENGLISH);
        if(TYPE_ALIASES.containsKey(key) && TYPE_ALIASES.get(key) != null && !((Class)TYPE_ALIASES.get(key)).equals(value))
        {
            throw new TypeException((new StringBuilder()).append("The alias '").append(alias).append("' is already mapped to the value '").append(((Class)TYPE_ALIASES.get(key)).getName()).append("'.").toString());
        } else
        {
            TYPE_ALIASES.put(key, value);
            return;
        }
    }
}

//初始化plugins
private void pluginElement(XNode parent)
        throws Exception
    {
        if(parent != null)
        {
            Interceptor interceptorInstance;
	    //添加插件configuration.addInterceptor(interceptorInstance)
            for(Iterator i$ = parent.getChildren().iterator(); i$.hasNext(); configuration.addInterceptor(interceptorInstance))
            {
                XNode child = (XNode)i$.next();
		//获取插件类
                String interceptor = child.getStringAttribute("interceptor");
		//获取插件属性
                Properties properties = child.getChildrenAsProperties();
                interceptorInstance = (Interceptor)resolveClass(interceptor).newInstance();
                interceptorInstance.setProperties(properties);
            }

        }
    }

来看插件的添加
//Configuration
  public void addInterceptor(Interceptor interceptor)
    {
        interceptorChain.addInterceptor(interceptor);
    }

//InterceptorChain
public class InterceptorChain
{
    public Object pluginAll(Object target)
    {
        for(Iterator i$ = interceptors.iterator(); i$.hasNext();)
        {
            Interceptor interceptor = (Interceptor)i$.next();
            target = interceptor.plugin(target);
        }

        return target;
    }
    public void addInterceptor(Interceptor interceptor)
    {
        interceptors.add(interceptor);
    }
    //实际上是添加到一个List<Interceptor>中
    private final List interceptors = new ArrayList();
}

//Interceptor
public interface Interceptor
{
    public abstract Object intercept(Invocation invocation)
        throws Throwable;
    public abstract Object plugin(Object obj);
    public abstract void setProperties(Properties properties);
}

//初始化ObjectFactory
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);
            configuration.setObjectFactory(factory);
        }
    }

//ObjectFactory
public interface ObjectFactory
{
    public abstract void setProperties(Properties properties);
    public abstract Object create(Class class1);
    public abstract Object create(Class class1, List list, List list1);
    public abstract boolean isCollection(Class class1);
}

//初始化ObjectWrapperFactory
  
 private void objectWrapperFactoryElement(XNode context)
        throws Exception
    {
        if(context != null)
        {
            String type = context.getStringAttribute("type");
            ObjectWrapperFactory factory = (ObjectWrapperFactory)resolveClass(type).newInstance();
            configuration.setObjectWrapperFactory(factory);
        }
    }

//ObjectWrapperFactory
public interface ObjectWrapperFactory
{
    public abstract boolean hasWrapperFor(Object obj);
    public abstract ObjectWrapper getWrapperFor(MetaObject metaobject, Object obj);
}

//初始化settings
private void settingsElement(XNode context)
        throws Exception
    {
        if(context != null)
        {
            Properties props = context.getChildrenAsProperties();
            MetaClass metaConfig = MetaClass.forClass(org/apache/ibatis/session/Configuration);
            for(Iterator i$ = props.keySet().iterator(); i$.hasNext();)
            {
                Object key = i$.next();
                if(!metaConfig.hasSetter(String.valueOf(key)))
                    throw new BuilderException((new StringBuilder()).append("The setting ").append(key).append(" is not known.  Make sure you spelled it correctly (case sensitive).").toString());
            }
           //配置configuration,是否懒加载,自动生成主键,全局映射缓存,本地以及缓存,
            configuration.setAutoMappingBehavior(AutoMappingBehavior.valueOf(props.getProperty("autoMappingBehavior", "PARTIAL")));
            configuration.setCacheEnabled(booleanValueOf(props.getProperty("cacheEnabled"), Boolean.valueOf(true)).booleanValue());
            //proxyFactory
	    configuration.setProxyFactory((ProxyFactory)createInstance(props.getProperty("proxyFactory")));
            configuration.setLazyLoadingEnabled(booleanValueOf(props.getProperty("lazyLoadingEnabled"), Boolean.valueOf(false)).booleanValue());
            configuration.setAggressiveLazyLoading(booleanValueOf(props.getProperty("aggressiveLazyLoading"), Boolean.valueOf(true)).booleanValue());
            configuration.setMultipleResultSetsEnabled(booleanValueOf(props.getProperty("multipleResultSetsEnabled"), Boolean.valueOf(true)).booleanValue());
            configuration.setUseColumnLabel(booleanValueOf(props.getProperty("useColumnLabel"), Boolean.valueOf(true)).booleanValue());
            configuration.setUseGeneratedKeys(booleanValueOf(props.getProperty("useGeneratedKeys"), Boolean.valueOf(false)).booleanValue());
            configuration.setDefaultExecutorType(ExecutorType.valueOf(props.getProperty("defaultExecutorType", "SIMPLE")));
            configuration.setDefaultStatementTimeout(integerValueOf(props.getProperty("defaultStatementTimeout"), null));
            configuration.setMapUnderscoreToCamelCase(booleanValueOf(props.getProperty("mapUnderscoreToCamelCase"), Boolean.valueOf(false)).booleanValue());
            configuration.setSafeRowBoundsEnabled(booleanValueOf(props.getProperty("safeRowBoundsEnabled"), Boolean.valueOf(false)).booleanValue());
            //localCacheScope,一级缓存作用域
	    configuration.setLocalCacheScope(LocalCacheScope.valueOf(props.getProperty("localCacheScope", "SESSION")));
            configuration.setJdbcTypeForNull(JdbcType.valueOf(props.getProperty("jdbcTypeForNull", "OTHER")));
            configuration.setLazyLoadTriggerMethods(stringSetValueOf(props.getProperty("lazyLoadTriggerMethods"), "equals,clone,hashCode,toString"));
            configuration.setDefaultScriptingLanguage(resolveClass(props.getProperty("defaultScriptingLanguage")));
            configuration.setCallSettersOnNulls(booleanValueOf(props.getProperty("callSettersOnNulls"), Boolean.valueOf(false)).booleanValue());
            configuration.setLogPrefix(props.getProperty("logPrefix"));
            configuration.setLogImpl(resolveClass(props.getProperty("logImpl")));
        }
    }

//初始化environments
private void environmentsElement(XNode context)
        throws Exception
    {
        if(context != null)
        {
            if(environment == null)
                environment = context.getStringAttribute("default");
            Iterator i$ = context.getChildren().iterator();
            do
            {
                if(!i$.hasNext())
                    break;
                XNode child = (XNode)i$.next();
                String id = child.getStringAttribute("id");
                if(isSpecifiedEnvironment(id))
                {
                    TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));
                    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);
        }
    }

//Environment
public final class Environment
{
    public static class Builder
    {

        public Builder transactionFactory(TransactionFactory transactionFactory)
        {
            this.transactionFactory = transactionFactory;
            return this;
        }

        public Builder dataSource(DataSource dataSource)
        {
            this.dataSource = dataSource;
            return this;
        }

        public String id()
        {
            return id;
        }

        public Environment build()
        {
            return new Environment(id, transactionFactory, dataSource);
        }

        private String id;
        private TransactionFactory transactionFactory;
        private DataSource dataSource;

        public Builder(String id)
        {
            this.id = id;
        }
    }
    private final String id;
    private final TransactionFactory transactionFactory;
    private final DataSource dataSource;
}

初始化typeHandler
private void typeHandlerElement(XNode parent)
        throws Exception
    {
        if(parent != null)
        {
            for(Iterator i$ = parent.getChildren().iterator(); i$.hasNext();)
            {
                XNode child = (XNode)i$.next();
                if("package".equals(child.getName()))
                {
                    String typeHandlerPackage = child.getStringAttribute("name");
                    typeHandlerRegistry.register(typeHandlerPackage);
                } else
                {
                    String javaTypeName = child.getStringAttribute("javaType");
                    String jdbcTypeName = child.getStringAttribute("jdbcType");
                    String handlerTypeName = child.getStringAttribute("handler");
                    Class javaTypeClass = resolveClass(javaTypeName);
                    JdbcType jdbcType = resolveJdbcType(jdbcTypeName);
                    Class typeHandlerClass = resolveClass(handlerTypeName);
                    if(javaTypeClass != null)
                    {
                        if(jdbcType == null)
                            typeHandlerRegistry.register(javaTypeClass, typeHandlerClass);
                        else
                            typeHandlerRegistry.register(javaTypeClass, jdbcType, typeHandlerClass);
                    } else
                    {
                        typeHandlerRegistry.register(typeHandlerClass);
                    }
                }
            }

        }
    }

//TypeHandlerRegistry
public final class TypeHandlerRegistry
{
    public TypeHandlerRegistry()
    {
        //初始化java,变量,JDBCTYPE,及对应的Handler映射
        register(java/lang/Boolean, new BooleanTypeHandler());
        register(Boolean.TYPE, new BooleanTypeHandler());
        register(JdbcType.BOOLEAN, new BooleanTypeHandler());
        register(JdbcType.BIT, new BooleanTypeHandler());
        register(java/lang/Byte, new ByteTypeHandler());
        register(Byte.TYPE, new ByteTypeHandler());
        register(JdbcType.TINYINT, new ByteTypeHandler());
        register(java/lang/Short, new ShortTypeHandler());
        register(Short.TYPE, new ShortTypeHandler());
        register(JdbcType.SMALLINT, new ShortTypeHandler());
        register(java/lang/Integer, new IntegerTypeHandler());
        register(Integer.TYPE, new IntegerTypeHandler());
        register(JdbcType.INTEGER, new IntegerTypeHandler());
        register(java/lang/Long, new LongTypeHandler());
        register(Long.TYPE, new LongTypeHandler());
        register(java/lang/Float, new FloatTypeHandler());
        register(Float.TYPE, new FloatTypeHandler());
        register(JdbcType.FLOAT, new FloatTypeHandler());
        register(java/lang/Double, new DoubleTypeHandler());
        register(Double.TYPE, new DoubleTypeHandler());
        register(JdbcType.DOUBLE, new DoubleTypeHandler());
        register(java/lang/String, new StringTypeHandler());
        register(java/lang/String, JdbcType.CHAR, new StringTypeHandler());
        register(java/lang/String, JdbcType.CLOB, new ClobTypeHandler());
        register(java/lang/String, JdbcType.VARCHAR, new StringTypeHandler());
        register(java/lang/String, JdbcType.LONGVARCHAR, new ClobTypeHandler());
        register(java/lang/String, JdbcType.NVARCHAR, new NStringTypeHandler());
        register(java/lang/String, JdbcType.NCHAR, new NStringTypeHandler());
        register(java/lang/String, JdbcType.NCLOB, new NClobTypeHandler());
        register(JdbcType.CHAR, new StringTypeHandler());
        register(JdbcType.VARCHAR, new StringTypeHandler());
        register(JdbcType.CLOB, new ClobTypeHandler());
        register(JdbcType.LONGVARCHAR, new ClobTypeHandler());
        register(JdbcType.NVARCHAR, new NStringTypeHandler());
        register(JdbcType.NCHAR, new NStringTypeHandler());
        register(JdbcType.NCLOB, new NClobTypeHandler());
        register(java/lang/Object, JdbcType.ARRAY, new ArrayTypeHandler());
        register(JdbcType.ARRAY, new ArrayTypeHandler());
        register(java/math/BigInteger, new BigIntegerTypeHandler());
        register(JdbcType.BIGINT, new LongTypeHandler());
        register(java/math/BigDecimal, new BigDecimalTypeHandler());
        register(JdbcType.REAL, new BigDecimalTypeHandler());
        register(JdbcType.DECIMAL, new BigDecimalTypeHandler());
        register(JdbcType.NUMERIC, new BigDecimalTypeHandler());
        register([Ljava/lang/Byte;, new ByteObjectArrayTypeHandler());
        register([Ljava/lang/Byte;, JdbcType.BLOB, new BlobByteObjectArrayTypeHandler());
        register([Ljava/lang/Byte;, JdbcType.LONGVARBINARY, new BlobByteObjectArrayTypeHandler());
        register([B, new ByteArrayTypeHandler());
        register([B, JdbcType.BLOB, new BlobTypeHandler());
        register([B, JdbcType.LONGVARBINARY, new BlobTypeHandler());
        register(JdbcType.LONGVARBINARY, new BlobTypeHandler());
        register(JdbcType.BLOB, new BlobTypeHandler());
        register(java/lang/Object, UNKNOWN_TYPE_HANDLER);
        register(java/lang/Object, JdbcType.OTHER, UNKNOWN_TYPE_HANDLER);
        register(JdbcType.OTHER, UNKNOWN_TYPE_HANDLER);
        register(java/util/Date, new DateTypeHandler());
        register(java/util/Date, JdbcType.DATE, new DateOnlyTypeHandler());
        register(java/util/Date, JdbcType.TIME, new TimeOnlyTypeHandler());
        register(JdbcType.TIMESTAMP, new DateTypeHandler());
        register(JdbcType.DATE, new DateOnlyTypeHandler());
        register(JdbcType.TIME, new TimeOnlyTypeHandler());
        register(java/sql/Date, new SqlDateTypeHandler());
        register(java/sql/Time, new SqlTimeTypeHandler());
        register(java/sql/Timestamp, new SqlTimestampTypeHandler());
        register(java/lang/Character, new CharacterTypeHandler());
        register(Character.TYPE, new CharacterTypeHandler());
    }

   //注册jdbcType和TypeHandler的映射
   public void register(JdbcType jdbcType, TypeHandler handler)
    {
        //JDBC_TYPE_HANDLER_MAP = new EnumMap(org/apache/ibatis/type/JdbcType);
        JDBC_TYPE_HANDLER_MAP.put(jdbcType, handler);
    }
    public void register(Class javaType, TypeHandler typeHandler)
    {
        register(((Type) (javaType)), typeHandler);
    }
    //注册javaType和TypeHandler的映射
    private void register(Type javaType, TypeHandler typeHandler)
    {
        MappedJdbcTypes mappedJdbcTypes = (MappedJdbcTypes)typeHandler.getClass().getAnnotation(org/apache/ibatis/type/MappedJdbcTypes);
        if(mappedJdbcTypes != null)
        {
            JdbcType arr$[] = mappedJdbcTypes.value();
            int len$ = arr$.length;
            for(int i$ = 0; i$ < len$; i$++)
            {
                JdbcType handledJdbcType = arr$[i$];
                register(javaType, handledJdbcType, typeHandler);
            }

            if(mappedJdbcTypes.includeNullJdbcType())
                register(javaType, null, typeHandler);
        } else
        {
            register(javaType, null, typeHandler);
        }
    }
    //注册javaTypeClass,jdbcType,typeHandlerClass的映射
    public void register(Class javaTypeClass, JdbcType jdbcType, Class typeHandlerClass)
    {
        register(((Type) (javaTypeClass)), jdbcType, getInstance(javaTypeClass, typeHandlerClass));
    }
    //获取TypeHandler,实例
    public TypeHandler getInstance(Class javaTypeClass, Class typeHandlerClass)
    {
        if(javaTypeClass == null)
            break MISSING_BLOCK_LABEL_69;
        Constructor c = typeHandlerClass.getConstructor(new Class[] {
            java/lang/Class
        });
        return (TypeHandler)c.newInstance(new Object[] {
            javaTypeClass
        });
    }
     //注册javaTypeClass,jdbcType,typeHandlerClass的映射关系
     private void register(Type javaType, JdbcType jdbcType, TypeHandler handler)
    {
        if(javaType != null)
        {
            Map map = (Map)TYPE_HANDLER_MAP.get(javaType);
            if(map == null)
            {
                map = new HashMap();
		//TYPE_HANDLER_MAP,TYPE_HANDLER_MAP<javaType,Map<JdbcType,TypeHandler>
                TYPE_HANDLER_MAP.put(javaType, map);
            }
            map.put(jdbcType, handler);
            if(reversePrimitiveMap.containsKey(javaType))
                register((Type)reversePrimitiveMap.get(javaType), jdbcType, handler);
        }
        ALL_TYPE_HANDLERS_MAP.put(handler.getClass(), handler);
    }
    private static final Map reversePrimitiveMap = new HashMap() {
        private static final long serialVersionUID = 1L;

            
            {
                put(java/lang/Byte, Byte.TYPE);
                put(java/lang/Short, Short.TYPE);
                put(java/lang/Integer, Integer.TYPE);
                put(java/lang/Long, Long.TYPE);
                put(java/lang/Float, Float.TYPE);
                put(java/lang/Double, Double.TYPE);
                put(java/lang/Boolean, Boolean.TYPE);
                put(java/lang/Character, Character.TYPE);
            }
    };
    private final Map JDBC_TYPE_HANDLER_MAP = new EnumMap(org/apache/ibatis/type/JdbcType);
    private final Map TYPE_HANDLER_MAP = new HashMap();
    private final TypeHandler UNKNOWN_TYPE_HANDLER = new UnknownTypeHandler(this);
    private final Map ALL_TYPE_HANDLERS_MAP = new HashMap();
}

//TypeHandler
public interface TypeHandler
{
    public abstract void setParameter(PreparedStatement preparedstatement, int i, Object obj, JdbcType jdbctype)
        throws SQLException;
    public abstract Object getResult(ResultSet resultset, String s)
        throws SQLException;
    public abstract Object getResult(ResultSet resultset, int i)
        throws SQLException;
    public abstract Object getResult(CallableStatement callablestatement, int i)
        throws SQLException;
}

//JdbcType
public final class JdbcType extends Enum
{
public static final JdbcType ARRAY;
    public static final JdbcType BIT;
    public static final JdbcType TINYINT;
    public static final JdbcType SMALLINT;
    public static final JdbcType INTEGER;
    public static final JdbcType BIGINT;
    public static final JdbcType FLOAT;
    public static final JdbcType REAL;
    public static final JdbcType DOUBLE;
    public static final JdbcType NUMERIC;
    public static final JdbcType DECIMAL;
    public static final JdbcType CHAR;
    public static final JdbcType VARCHAR;
    public static final JdbcType LONGVARCHAR;
    public static final JdbcType DATE;
    public static final JdbcType TIME;
    public static final JdbcType TIMESTAMP;
    public static final JdbcType BINARY;
    public static final JdbcType VARBINARY;
    public static final JdbcType LONGVARBINARY;
    public static final JdbcType NULL;
    public static final JdbcType OTHER;
    public static final JdbcType BLOB;
    public static final JdbcType CLOB;
    public static final JdbcType BOOLEAN;
    public static final JdbcType CURSOR;
    public static final JdbcType UNDEFINED;
    public static final JdbcType NVARCHAR;
    public static final JdbcType NCHAR;
    public static final JdbcType NCLOB;
    public static final JdbcType STRUCT;
    public final int TYPE_CODE;
    private static Map codeLookup;
    private static final JdbcType $VALUES[];

    static 
    {
        ARRAY = new JdbcType("ARRAY", 0, 2003);
        BIT = new JdbcType("BIT", 1, -7);
        TINYINT = new JdbcType("TINYINT", 2, -6);
        SMALLINT = new JdbcType("SMALLINT", 3, 5);
        INTEGER = new JdbcType("INTEGER", 4, 4);
        BIGINT = new JdbcType("BIGINT", 5, -5);
        FLOAT = new JdbcType("FLOAT", 6, 6);
        REAL = new JdbcType("REAL", 7, 7);
        DOUBLE = new JdbcType("DOUBLE", 8, 8);
        NUMERIC = new JdbcType("NUMERIC", 9, 2);
        DECIMAL = new JdbcType("DECIMAL", 10, 3);
        CHAR = new JdbcType("CHAR", 11, 1);
        VARCHAR = new JdbcType("VARCHAR", 12, 12);
        LONGVARCHAR = new JdbcType("LONGVARCHAR", 13, -1);
        DATE = new JdbcType("DATE", 14, 91);
        TIME = new JdbcType("TIME", 15, 92);
        TIMESTAMP = new JdbcType("TIMESTAMP", 16, 93);
        BINARY = new JdbcType("BINARY", 17, -2);
        VARBINARY = new JdbcType("VARBINARY", 18, -3);
        LONGVARBINARY = new JdbcType("LONGVARBINARY", 19, -4);
        NULL = new JdbcType("NULL", 20, 0);
        OTHER = new JdbcType("OTHER", 21, 1111);
        BLOB = new JdbcType("BLOB", 22, 2004);
        CLOB = new JdbcType("CLOB", 23, 2005);
        BOOLEAN = new JdbcType("BOOLEAN", 24, 16);
        CURSOR = new JdbcType("CURSOR", 25, -10);
        UNDEFINED = new JdbcType("UNDEFINED", 26, -2147482648);
        NVARCHAR = new JdbcType("NVARCHAR", 27, -9);
        NCHAR = new JdbcType("NCHAR", 28, -15);
        NCLOB = new JdbcType("NCLOB", 29, 2011);
        STRUCT = new JdbcType("STRUCT", 30, 2002);
        $VALUES = (new JdbcType[] {
            ARRAY, BIT, TINYINT, SMALLINT, INTEGER, BIGINT, FLOAT, REAL, DOUBLE, NUMERIC, 
            DECIMAL, CHAR, VARCHAR, LONGVARCHAR, DATE, TIME, TIMESTAMP, BINARY, VARBINARY, LONGVARBINARY, 
            NULL, OTHER, BLOB, CLOB, BOOLEAN, CURSOR, UNDEFINED, NVARCHAR, NCHAR, NCLOB, 
            STRUCT
        });
        codeLookup = new HashMap();
        JdbcType arr$[] = values();
        int len$ = arr$.length;
        for(int i$ = 0; i$ < len$; i$++)
        {
            JdbcType type = arr$[i$];
            codeLookup.put(Integer.valueOf(type.TYPE_CODE), type);
        }

    }
}

从上面可以看出;初始化typeHandler,就是初始化javaType,jdbcType,及TypeHandler的映射关系
初始化mappers
 private void mapperElement(XNode parent)
        throws Exception
    {
        if(parent != null)
        {
            for(Iterator i$ = parent.getChildren().iterator(); i$.hasNext();)
            {
                XNode child = (XNode)i$.next();
                if("package".equals(child.getName()))
                {
                    String mapperPackage = child.getStringAttribute("name");
                    configuration.addMappers(mapperPackage);
                } else
                {
                    String resource = child.getStringAttribute("resource");
                    String url = child.getStringAttribute("url");
                    String mapperClass = child.getStringAttribute("class");
                    if(resource != null && url == null && mapperClass == null)
                    {
                        ErrorContext.instance().resource(resource);
			//加载Mapper的resource文件
                        InputStream inputStream = Resources.getResourceAsStream(resource);
		        构建XMLMapperBuilder
                        XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
                        mapperParser.parse();
                    } else
                    if(resource == null && url != null && mapperClass == null)
                    {
                        ErrorContext.instance().resource(url);
                        InputStream inputStream = Resources.getUrlAsStream(url);
                        XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments());
                        mapperParser.parse();
                    } else
                    if(resource == null && url == null && mapperClass != null)
                    {
                        Class mapperInterface = Resources.classForName(mapperClass);
		        //mapperInterface信息添加到configuration
                        configuration.addMapper(mapperInterface);
                    } else
                    {
                        throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
                    }
                }
            }

        }
    }

回到SqlSessionFactoryBuilder,可以看到builder实际上是返回的是DefaultSqlSessionFactory
public SqlSessionFactory build(Configuration config)
    {
        return new DefaultSqlSessionFactory(config);
    }

总结:
从上,可以出SqlSessionFactoryBuilder做的主要工作是,加载全局配置文件,根据
properties,typeAliases,plugins,objectFactory,objectWrapperFactory
,settings,environments,databaseIdProvider,typeHandlers,mappers配置项,
初始化Configuration,由于mappers解析内容较多,我们放在下一篇来讲。
附:Mapper解析的引篇
//Configuration
   public void addMapper(Class type)
    {
        mapperRegistry.addMapper(type);
    }

//MapperRegistry
public class MapperRegistry
{ public void addMapper(Class type)
    {
        boolean loadCompleted;
        if(!type.isInterface())
            break MISSING_BLOCK_LABEL_125;
        if(hasMapper(type))
            throw new BindingException((new StringBuilder()).append("Type ").append(type).append(" is already known to the MapperRegistry.").toString());
        loadCompleted = false;
        knownMappers.put(type, new MapperProxyFactory(type));
        MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
        parser.parse();
        loadCompleted = true;
        if(!loadCompleted)
            knownMappers.remove(type);
        break MISSING_BLOCK_LABEL_125;
        Exception exception;
        exception;
        if(!loadCompleted)
            knownMappers.remove(type);
        throw exception;
    }
    private Configuration config;
    //HashMap<Class,MapperProxyFactory>
    private final Map knownMappers = new HashMap();
}

//MapperProxyFactory
public class MapperProxyFactory
{
    public MapperProxyFactory(Class mapperInterface)
    {
        methodCache = new ConcurrentHashMap();
        this.mapperInterface = mapperInterface;
    }
     protected Object newInstance(MapperProxy mapperProxy)
    {
        //代理生成实例
        return Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] {
            mapperInterface
        }, mapperProxy);
    }

    public Object newInstance(SqlSession sqlSession)
    {
        MapperProxy mapperProxy = new MapperProxy(sqlSession, mapperInterface, methodCache);
        return newInstance(mapperProxy);
    }
    private final Class mapperInterface;
    private Map methodCache;
}

//MapperProxy
public class MapperProxy
    implements InvocationHandler, Serializable
{
    public MapperProxy(SqlSession sqlSession, Class mapperInterface, Map methodCache)
    {
        this.sqlSession = sqlSession;
        this.mapperInterface = mapperInterface;
        this.methodCache = methodCache;
    }
    public Object invoke(Object proxy, Method method, Object args[])
        throws Throwable
    {
        if(java/lang/Object.equals(method.getDeclaringClass()))
        {
            return method.invoke(this, args);
        } else
        {
            MapperMethod mapperMethod = cachedMapperMethod(method);
            return mapperMethod.execute(sqlSession, args);
        }
    }
    private MapperMethod cachedMapperMethod(Method method)
    {
        MapperMethod mapperMethod = (MapperMethod)methodCache.get(method);
        if(mapperMethod == null)
        {
            mapperMethod = new MapperMethod(mapperInterface, method, sqlSession.getConfiguration());
            methodCache.put(method, mapperMethod);
        }
        return mapperMethod;
    }

    private static final long serialVersionUID = -6424540398559729838L;
    private final SqlSession sqlSession;
    private final Class mapperInterface;
    //Map<Method,MapperMethod>,即二级缓存
    private final Map methodCache;
}

从上可以看出Configuration添加MapperInterface,就是MapperRegistry注册到其
HashMap<Class,MapperProxyFactory>中,MapperProxyFactory是MapperInterface的代理,
生成MapperInterface的MapperProxy代理实例,MapperProxy中利用Map<Method,MapperMethod>,
实现二级缓存
//MapperAnnotationBuilder,MapperInterface的注解处理
public class MapperAnnotationBuilder
{

    public MapperAnnotationBuilder(Configuration configuration, Class type)
    {
        String resource = (new StringBuilder()).append(type.getName().replace('.', '/')).append(".java (best guess)").toString();
        assistant = new MapperBuilderAssistant(configuration, resource);
        this.configuration = configuration;
        this.type = type;
        sqlAnnotationTypes.add(org/apache/ibatis/annotations/Select);
        sqlAnnotationTypes.add(org/apache/ibatis/annotations/Insert);
        sqlAnnotationTypes.add(org/apache/ibatis/annotations/Update);
        sqlAnnotationTypes.add(org/apache/ibatis/annotations/Delete);
        sqlProviderAnnotationTypes.add(org/apache/ibatis/annotations/SelectProvider);
        sqlProviderAnnotationTypes.add(org/apache/ibatis/annotations/InsertProvider);
        sqlProviderAnnotationTypes.add(org/apache/ibatis/annotations/UpdateProvider);
        sqlProviderAnnotationTypes.add(org/apache/ibatis/annotations/DeleteProvider);
    }
    //解析CacheNamespace注解
     private void parseCache()
    {
        CacheNamespace cacheDomain = (CacheNamespace)type.getAnnotation(org/apache/ibatis/annotations/CacheNamespace);
        if(cacheDomain != null)
            assistant.useNewCache(cacheDomain.implementation(), cacheDomain.eviction(), Long.valueOf(cacheDomain.flushInterval()), Integer.valueOf(cacheDomain.size()), cacheDomain.readWrite(), null);
    }
    //解析CacheNamespaceRef注解
    private void parseCacheRef()
    {
        CacheNamespaceRef cacheDomainRef = (CacheNamespaceRef)type.getAnnotation(org/apache/ibatis/annotations/CacheNamespaceRef);
        if(cacheDomainRef != null)
            assistant.useCacheRef(cacheDomainRef.value().getName());
    }
    private String parseResultMap(Method method)
    {
        Class returnType = getReturnType(method);
        ConstructorArgs args = (ConstructorArgs)method.getAnnotation(org/apache/ibatis/annotations/ConstructorArgs);
        Results results = (Results)method.getAnnotation(org/apache/ibatis/annotations/Results);
        TypeDiscriminator typeDiscriminator = (TypeDiscriminator)method.getAnnotation(org/apache/ibatis/annotations/TypeDiscriminator);
        String resultMapId = generateResultMapName(method);
        applyResultMap(resultMapId, returnType, argsIf(args), resultsIf(results), typeDiscriminator);
        return resultMapId;
    }
    //处理Statement方法method
    void parseStatement(Method method)
    {}
    private final Set sqlAnnotationTypes = new HashSet();
    private final Set sqlProviderAnnotationTypes = new HashSet();
    private Configuration configuration;
    private MapperBuilderAssistant assistant;
    private Class type;
}


猜你喜欢

转载自donald-draper.iteye.com/blog/2331917