博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MyBatis源码解析(一)
阅读量:4313 次
发布时间:2019-06-06

本文共 16112 字,大约阅读时间需要 53 分钟。

dialect=mysql

下面跟踪SqlSessionFactoryBean.java的源码

public class SqlSessionFactoryBean implements FactoryBean
, InitializingBean, ApplicationListener
{}

 

 实现了InitializingBean,ApplicationListener,自然而然就会在Spring加载的过程中做一些操作:

public void afterPropertiesSet() throws Exception {        Assert.notNull(this.dataSource, "Property 'dataSource' is required");        Assert.notNull(this.sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");        Assert.state(this.configuration == null && this.configLocation == null || this.configuration == null || this.configLocation == null, "Property 'configuration' and 'configLocation' can not specified with together");        this.sqlSessionFactory = this.buildSqlSessionFactory();    }
this.buildSqlSessionFactory();这个就是核心重点!!!
protected SqlSessionFactory buildSqlSessionFactory() throws IOException {        XMLConfigBuilder xmlConfigBuilder = null;        Configuration targetConfiguration;        if (this.configuration != null) {            targetConfiguration = this.configuration;            if (targetConfiguration.getVariables() == null) {                targetConfiguration.setVariables(this.configurationProperties);            } else if (this.configurationProperties != null) {                targetConfiguration.getVariables().putAll(this.configurationProperties);            }        } else if (this.configLocation != null) {            xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), (String)null, this.configurationProperties);            targetConfiguration = xmlConfigBuilder.getConfiguration();        } else {            LOGGER.debug(() -> {                return "Property 'configuration' or 'configLocation' not specified, using default MyBatis Configuration";            });            targetConfiguration = new Configuration();            Optional.ofNullable(this.configurationProperties).ifPresent(targetConfiguration::setVariables);        }        Optional.ofNullable(this.objectFactory).ifPresent(targetConfiguration::setObjectFactory);        Optional.ofNullable(this.objectWrapperFactory).ifPresent(targetConfiguration::setObjectWrapperFactory);        Optional.ofNullable(this.vfs).ifPresent(targetConfiguration::setVfsImpl);        String[] typeHandlersPackageArray;        if (StringUtils.hasLength(this.typeAliasesPackage)) {            typeHandlersPackageArray = StringUtils.tokenizeToStringArray(this.typeAliasesPackage, ",; \t\n");            Stream.of(typeHandlersPackageArray).forEach((packageToScan) -> {                targetConfiguration.getTypeAliasRegistry().registerAliases(packageToScan, this.typeAliasesSuperType == null ? Object.class : this.typeAliasesSuperType);                LOGGER.debug(() -> {                    return "Scanned package: '" + packageToScan + "' for aliases";                });            });        }        if (!ObjectUtils.isEmpty(this.typeAliases)) {            Stream.of(this.typeAliases).forEach((typeAlias) -> {                targetConfiguration.getTypeAliasRegistry().registerAlias(typeAlias);                LOGGER.debug(() -> {                    return "Registered type alias: '" + typeAlias + "'";                });            });        }        if (!ObjectUtils.isEmpty(this.plugins)) {            Stream.of(this.plugins).forEach((plugin) -> {                targetConfiguration.addInterceptor(plugin);                LOGGER.debug(() -> {                    return "Registered plugin: '" + plugin + "'";                });            });        }        if (StringUtils.hasLength(this.typeHandlersPackage)) {            typeHandlersPackageArray = StringUtils.tokenizeToStringArray(this.typeHandlersPackage, ",; \t\n");            Stream.of(typeHandlersPackageArray).forEach((packageToScan) -> {                targetConfiguration.getTypeHandlerRegistry().register(packageToScan);                LOGGER.debug(() -> {                    return "Scanned package: '" + packageToScan + "' for type handlers";                });            });        }        if (!ObjectUtils.isEmpty(this.typeHandlers)) {            Stream.of(this.typeHandlers).forEach((typeHandler) -> {                targetConfiguration.getTypeHandlerRegistry().register(typeHandler);                LOGGER.debug(() -> {                    return "Registered type handler: '" + typeHandler + "'";                });            });        }        if (this.databaseIdProvider != null) {            try {                targetConfiguration.setDatabaseId(this.databaseIdProvider.getDatabaseId(this.dataSource));            } catch (SQLException var23) {                throw new NestedIOException("Failed getting a databaseId", var23);            }        }        Optional.ofNullable(this.cache).ifPresent(targetConfiguration::addCache);        if (xmlConfigBuilder != null) {            try {                xmlConfigBuilder.parse();                LOGGER.debug(() -> {                    return "Parsed configuration file: '" + this.configLocation + "'";                });            } catch (Exception var21) {                throw new NestedIOException("Failed to parse config resource: " + this.configLocation, var21);            } finally {                ErrorContext.instance().reset();            }        }        targetConfiguration.setEnvironment(new Environment(this.environment, (TransactionFactory)(this.transactionFactory == null ? new SpringManagedTransactionFactory() : this.transactionFactory), this.dataSource));        if (!ObjectUtils.isEmpty(this.mapperLocations)) {            Resource[] var24 = this.mapperLocations;            int var4 = var24.length;            for(int var5 = 0; var5 < var4; ++var5) {                Resource mapperLocation = var24[var5];                if (mapperLocation != null) {                    try {                        XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(), targetConfiguration, mapperLocation.toString(), targetConfiguration.getSqlFragments());                        xmlMapperBuilder.parse();                    } catch (Exception var19) {                        throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", var19);                    } finally {                        ErrorContext.instance().reset();                    }                    LOGGER.debug(() -> {                        return "Parsed mapper file: '" + mapperLocation + "'";                    });                }            }        } else {            LOGGER.debug(() -> {                return "Property 'mapperLocations' was not specified or no matching resources found";            });        }        return this.sqlSessionFactoryBuilder.build(targetConfiguration);    }

这个方法我们慢慢仔细看:

XMLConfigBuilder xmlConfigBuilder = null;        Configuration targetConfiguration;        if (this.configuration != null) {            targetConfiguration = this.configuration;            if (targetConfiguration.getVariables() == null) {                targetConfiguration.setVariables(this.configurationProperties);            } else if (this.configurationProperties != null) {                targetConfiguration.getVariables().putAll(this.configurationProperties);            }        } else if (this.configLocation != null) {            xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), (String)null, this.configurationProperties);            targetConfiguration = xmlConfigBuilder.getConfiguration();        } else {            LOGGER.debug(() -> {                return "Property 'configuration' or 'configLocation' not specified, using default MyBatis Configuration";            });            targetConfiguration = new Configuration();            Optional.ofNullable(this.configurationProperties).ifPresent(targetConfiguration::setVariables);        }

上面中标红的就是核心代码,

public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {    this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);  }
public XPathParser(InputStream inputStream, boolean validation, Properties variables, EntityResolver entityResolver) {    commonConstructor(validation, variables, entityResolver);    this.document = createDocument(new InputSource(inputStream));  }
private Document createDocument(InputSource inputSource) {    // important: this must only be called AFTER common constructor    try {      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();      factory.setValidating(validation);      factory.setNamespaceAware(false);      factory.setIgnoringComments(true);      factory.setIgnoringElementContentWhitespace(false);      factory.setCoalescing(false);      factory.setExpandEntityReferences(true);      DocumentBuilder builder = factory.newDocumentBuilder();      builder.setEntityResolver(entityResolver);      builder.setErrorHandler(new ErrorHandler() {        @Override        public void error(SAXParseException exception) throws SAXException {          throw exception;        }        @Override        public void fatalError(SAXParseException exception) throws SAXException {          throw exception;        }        @Override        public void warning(SAXParseException exception) throws SAXException {        }      });      return builder.parse(inputSource);    } catch (Exception e) {      throw new BuilderException("Error creating document instance.  Cause: " + e, e);    }  }
public Document parse(InputSource is) throws SAXException, IOException {        if (is == null) {            throw new IllegalArgumentException(                DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN,                "jaxp-null-input-source", null));        }        if (fSchemaValidator != null) {            if (fSchemaValidationManager != null) {                fSchemaValidationManager.reset();                fUnparsedEntityHandler.reset();            }            resetSchemaValidator();        }        domParser.parse(is);        Document doc = domParser.getDocument();        domParser.dropDocumentReferences();        return doc;    }
configLocation就算解析完成了;其他的
typeAliasesPackage,plugins都没什么好看的,不过
plugins中通过添加interceptor完成插件的拦截入口,常用的就是PageHelper分页插件,后面可以具体看看这个是如何生效的!!
if (!ObjectUtils.isEmpty(this.plugins)) {            Stream.of(this.plugins).forEach((plugin) -> {                targetConfiguration.addInterceptor(plugin);                LOGGER.debug(() -> {                    return "Registered plugin: '" + plugin + "'";                });            });        }

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

protected final MapperRegistry mapperRegistry = new MapperRegistry(this);
public class Configuration {  protected Environment environment;  protected boolean safeRowBoundsEnabled = false;  protected boolean safeResultHandlerEnabled = true;  protected boolean mapUnderscoreToCamelCase = false;  protected boolean aggressiveLazyLoading = true;  protected boolean multipleResultSetsEnabled = true;  protected boolean useGeneratedKeys = false;  protected boolean useColumnLabel = true;  protected boolean cacheEnabled = true;  protected boolean callSettersOnNulls = false;  protected boolean useActualParamName = true;  protected String logPrefix;  protected Class 
logImpl; protected Class
vfsImpl; protected LocalCacheScope localCacheScope = LocalCacheScope.SESSION; protected JdbcType jdbcTypeForNull = JdbcType.OTHER; protected Set
lazyLoadTriggerMethods = new HashSet
(Arrays.asList(new String[] { "equals", "clone", "hashCode", "toString" })); protected Integer defaultStatementTimeout; protected Integer defaultFetchSize; protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE; protected AutoMappingBehavior autoMappingBehavior = AutoMappingBehavior.PARTIAL; protected AutoMappingUnknownColumnBehavior autoMappingUnknownColumnBehavior = AutoMappingUnknownColumnBehavior.NONE; protected Properties variables = new Properties(); protected ReflectorFactory reflectorFactory = new DefaultReflectorFactory(); protected ObjectFactory objectFactory = new DefaultObjectFactory(); protected ObjectWrapperFactory objectWrapperFactory = new DefaultObjectWrapperFactory(); protected boolean lazyLoadingEnabled = false; protected ProxyFactory proxyFactory = new JavassistProxyFactory(); // #224 Using internal Javassist instead of OGNL protected String databaseId; /** * Configuration factory class. * Used to create Configuration for loading deserialized unread properties. * * @see
Issue 300 (google code) */ protected Class
configurationFactory; protected final MapperRegistry mapperRegistry = new MapperRegistry(this); protected final InterceptorChain interceptorChain = new InterceptorChain(); protected final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry(); protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry(); protected final LanguageDriverRegistry languageRegistry = new LanguageDriverRegistry(); protected final Map
mappedStatements = new StrictMap
("Mapped Statements collection"); protected final Map
caches = new StrictMap
("Caches collection"); protected final Map
resultMaps = new StrictMap
("Result Maps collection"); protected final Map
parameterMaps = new StrictMap
("Parameter Maps collection"); protected final Map
keyGenerators = new StrictMap
("Key Generators collection"); protected final Set
loadedResources = new HashSet
(); protected final Map
sqlFragments = new StrictMap
("XML fragments parsed from previous mappers"); protected final Collection
incompleteStatements = new LinkedList
(); protected final Collection
incompleteCacheRefs = new LinkedList
(); protected final Collection
incompleteResultMaps = new LinkedList
(); protected final Collection
incompleteMethods = new LinkedList
(); /* * A map holds cache-ref relationship. The key is the namespace that * references a cache bound to another namespace and the value is the * namespace which the actual cache is bound to. */ protected final Map
cacheRefMap = new HashMap
(); public Configuration(Environment environment) { this(); this.environment = environment; } 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); }

 

 

 

转载于:https://www.cnblogs.com/longxok/p/10855691.html

你可能感兴趣的文章
给button添加UAC的小盾牌图标
查看>>
如何退出 vim
查看>>
Robberies
查看>>
get post 提交
查看>>
R安装
查看>>
跟我一起学C++
查看>>
Android自动化测试之环境搭建
查看>>
JavaScript运算符
查看>>
html position布局
查看>>
VTP
查看>>
Linux内核分析第一周——计算机是如何工作的
查看>>
Windows 自动启动 bat
查看>>
不规则按钮,支持普通Button,Radio Button, Check Button
查看>>
【C语言】模拟实现库函数strcat函数
查看>>
用newLISP读取Hive的元数据
查看>>
模式识别 - libsvm该函数的调用方法 详细说明
查看>>
数据库启动(下一个)
查看>>
FineUI第九天---表单验证
查看>>
Unity3D 快捷键
查看>>
Springboot集成WebSocket通信全部代码,即扣即用。
查看>>