一:先思考几个问题

1:BlogMapper是个接口,接口不能实例化,如何间接调用selectBlog并返回

public interface BlogMapper {    public Blog selectBlog(Long id);}
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);Blog blog = mapper.selectBlog(1L);
mybatis通过jdk提供动静代理解决以上问题,例如:
BlogMapper b = (BlogMapper) Proxy.        newProxyInstance(JdkProxy.class.getClassLoader(), new Class[]{BlogMapper.class}, new InvocationHandler() {    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        //在调用selectBlog办法的时候执行invoke        if (method.getName().equals("selectBlog"))            System.out.println(method.getName()); return null; }});b.selectBlog(1l);

2:XML解析

解析xml的形式有多种,DOM,SAX,DOM4J,JDOM各有优劣。mybatis通过SAX解析xml,并结构须要的对象及性能,XML映射接口性能

二:源码入口

String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory =        new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);Blog blog = mapper.selectBlog(1L);

1:加载xml,ClassLoaderWrapper装璜模式加强ClassLoader性能

//mybatis封装Resources加载xml,实际上是调用classLoaderWrapper.getResourceAsStreamResources.getResourceAsStream(resource);//ClassLoaderWrapper##getResourceAsStreampublic static InputStream getResourceAsStream(ClassLoader loader, String resource) throws IOException {  InputStream in = classLoaderWrapper.getResourceAsStream(resource, loader); if (in == null) {    throw new IOException("Could not find resource " + resource); }  return in;}//ClassLoaderWrapper##getResourceAsStreampublic InputStream getResourceAsStream(String resource, ClassLoader classLoader) {  return getResourceAsStream(resource, getClassLoaders(classLoader));}InputStream getResourceAsStream(String resource, ClassLoader[] classLoader) {  for (ClassLoader cl : classLoader) {    if (null != cl) {        //加载资源        InputStream returnValue = cl.getResourceAsStream(resource);        if (null == returnValue) {            //再次加载资源            returnValue = cl.getResourceAsStream("/" + resource);        }        if (null != returnValue) {            return returnValue;        }    } }  return null;}//ClassLoaderWrapper获取多级类加载器加载xmlClassLoader[] getClassLoaders(ClassLoader classLoader) {  return new ClassLoader[]{      //参数指定的类加载器      classLoader, //零碎指定的默认加载器 defaultClassLoader, //以后线程的类加载器 Thread.currentThread().getContextClassLoader(), //以后类应用的类加载器 getClass().getClassLoader(), //JVM启动时就加载了类加载器 systemClassLoader};}

2:SqlSessionFactoryBuilder

SqlSessionFactoryBuilder次要构建SqlSessionFactory,SqlSessionFactory构建SqlSession,SqlSession次要对数据库增删改查进行了封装

上图基本上是mybatis的壳,为对外的接口类关系看看build()办法中的细节
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {  try {    //mybatis-config.xml 创立XMLConfigBuilderxml解析类    XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);    //返回DefaultSqlSessionFactory##Configuration    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 parser = new XMLConfigBuilder(inputStream, environment, properties);//XMLConfigBuilder为次要解析xml类,其中次要调用封装的XPathParser解析public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {  this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);}private XMLConfigBuilder(XPathParser parser, String environment, Properties props) { //new Configuration()调用父类构造方法初始化一些值 super(new Configuration()); ErrorContext.instance().resource("SQL Mapper Configuration"); this.configuration.setVariables(props); this.parsed = false; this.environment = environment; this.parser = parser;}public XPathParser(InputStream inputStream, boolean validation, Properties variables, EntityResolver entityResolver) {  commonConstructor(validation, variables, entityResolver);  //createDocument依据xml构建文档对象  this.document = createDocument(new InputSource(inputStream));}

mybatis用建造者模式结构Configuration这个次要类,这个类次要蕴含数据源信息,别名缓存,mapper映射缓存等等,从super(new Configuration())开始构建Configuration,传递给其余子类构建Configuration其余属性