Mybatis深入之初始化过程

Mybatis深入之初始化过程一:简介 这篇开始是根据Mybatis源码来对Mybatis进行更深入的学习、当然、精力有限、还做不到学习的面面俱到。Mybatis初始化过程可以用一句话概括:就是将Mybatis的配置信息加载到一个类中、供后面Mybatis进行各种操作时使用、这个类叫:Configuration——见名知意。当然这个类的功能并不仅限与存放配置文件信息。二:整体流程下面是一段正常情况下从加载配置到执行sql语句的代码:String mybatisConfigPath = “config/mybatis/mybatis.xml”;InputStream inputStream = Resources.getResourceAsStream(mybatisConfigPath);sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();int count = (Integer)sqlSession.selectOne(“org.alien.mybatis.samples.mapper.AuthorMapper.getAllAuthorsCount”);System.out.println(count);

初始化过程在上面代码中就是获取SqlSessionFactory的过程。 初始化过程流程图:

参照流程图、初始化大致步骤:

三:详细过程3.1 加载配置文件

这一步很简单、从代码层面上来看就是将配置文件以流的形式读取到程序中、并将其作为参数传递给SqlSessionFactoryBuilder以供后面创建SqlSessionFactory。其提供了许多重载的方法供我们选择:

但是其最后都是调用核心方法(从这里也可以看出、初始化过程就是构造填充Configuration过程):

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.}} } public SqlSessionFactory build(Configuration config) {return new DefaultSqlSessionFactory(config); }3.2解析配置文件

解析配置文件的入口是在SqlSessionFactoryBuilder中的:public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties)

流程图:

3.2.1 整理流程:调用XMLConfigBuilder.parse()创建Configuration对象并将配置文件信息装配到Configuration对象中. 下面从代码的角度来看上面流程主要代码。这里从代码执行角度进行分析。3.2.2 代码流程从SqlSessionFactoryBuilder.build()开始: public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {try {//创建解析文件并装配Configuration的类XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);//这里分开写、清楚一点。解析配置文件、装配Configuration并返回Configuration configuration = parser.parse();//根据Configuration创建SqlSessionFactory并返回return build(configuration);} 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 parser = new XMLConfigBuilder(inputStream, environment, properties);到底创建了一个什么样的XMLConfigBuilder。 具体构造方法:

public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props); }这里只关心inputstream参数、其他的可以自行研究、其实是不同build方法传递的不同参数。从上面可以看出要想先构建XMLConfigBuilder、首先需要创建XMLMapperEntityResolver、并以其作为创建XPathParser对象的参数之一。

2、XMLMapperEntityResolver的创建:new XMLMapperEntityResolver()、即只需调用其无参构造函数即可。其源码就不再贴了、就是将Mybatis的DTD文件加载到一个私有集合中private static final Map<String, String> doctypeMap = new HashMap<String, String>();并向外提供一个用户获取DTD的InputSource的方法public InputSource resolveEntity(String publicId, String systemId);

3、XPathParser的创建:

public XPathParser(InputStream inputStream, boolean validation, Properties variables, EntityResolver entityResolver) {//填充XPathParser 部分私有属性commonConstructor(validation, variables, entityResolver);//根据InputStream来创建Document对象用于后面操作配置文件。this.document = createDocument(new InputSource(inputStream)); }EntityResolver就是前面的XMLMapperEntityResolverInputStream则是配置文件流信息 (boolean validation, Properties variables, EntityResolver entityResolver) {this.validation = validation;this.entityResolver = entityResolver;this.variables = variables;XPathFactory factory = XPathFactory.newInstance();this.xpath = factory.newXPath(); }设置解析xml文件时使用的属性 private Document createDocument(InputSource inputSource) {// important: this must only be called AFTER common constructortry {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() {(SAXParseException exception) throws SAXException {throw exception;}(SAXParseException exception) throws SAXException {throw exception;}(SAXParseException exception) throws SAXException {}});return builder.parse(inputSource);} catch (Exception e) {throw new BuilderException(“Error creating document instance. Cause: ” + e, e);} }根据InputSource创建Document 3、当XPathParser创建完成之后、回到真正执行XMLConfigBuilder创建的方法: private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {super(new Configuration());ErrorContext.instance().resource(“SQL Mapper Configuration”);//解析文件代码只能执行一次、当解析之后此值将变为truethis.parsed = false;this.environment = environment;//前面实例化好的XPathParserthis.parser = parser; }学会宽容,要有一颗宽容的爱心!

Mybatis深入之初始化过程

相关文章:

你感兴趣的文章:

标签云: