在解析mybatis源码时,通过用例
public static void main(String[] args)throws Exception{
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
List<SysParam> sysParamList = sqlSession.selectList("com.wolf.sty.mapper.SysParamMapper.selectList","30");
System.out.println(JSON.toJSONString(sysParamList));
}
本章主要分析
String resource = "mybatis-config.xml";
//如何被加载的
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new
mybatis-config.xml配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="mysql.properties"/>
<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>
<mappers>
<mapper resource="mapper/SysParamMapper.xml"/>
<!--<package name="mapper"/>-->
</mappers>
</configuration>
开始分析如何加载mybatis-config.xml
String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource);
在mybatis中通过Resources.getResourceAsStream()进行加载intputStream
Resources.class
//属性
private static ClassLoaderWrapper classLoaderWrapper = new ClassLoaderWrapper();
//
public static InputStream getResourceAsStream(String resource) throws IOException {
return getResourceAsStream(null, resource);
}
//调用重载方法
public static InputStream getResourceAsStream(ClassLoader loader, String resource) throws IOException {
//这里调用了classLoaderWrapper的getResourceAsStream
InputStream in = classLoaderWrapper.getResourceAsStream(resource, loader);
//如果返回的InputStream为空,即表示给定路径的资源没找到,抛出IO加载异常
if (in == null) {
throw new IOException("Could not find resource " + resource);
}
return in;
}
ClassLoaderWrapper.class资源加载包装器
public class ClassLoaderWrapper {
//默认类加载器
ClassLoader defaultClassLoader;
//系统加载器
ClassLoader systemClassLoader;
ClassLoaderWrapper() {
try {
systemClassLoader = ClassLoader.getSystemClassLoader();
} catch (SecurityException ignored) {
// AccessControlException on Google App Engine
}
}
/**
* Get a resource as a URL using the current class path
*
* @param resource - the resource to locate
* @return the resource or null
*/
public URL getResourceAsURL(String resource) {
return getResourceAsURL(resource, getClassLoaders(null));
}
/**
* Get a resource from the classpath, starting with a specific class loader
*
* @param resource - the resource to find
* @param classLoader - the first classloader to try
* @return the stream or null
*/
public URL getResourceAsURL(String resource, ClassLoader classLoader) {
return getResourceAsURL(resource, getClassLoaders(classLoader));
}
/**
* Get a resource from the classpath
*
* @param resource - the resource to find
* @return the stream or null
*/
public InputStream getResourceAsStream(String resource) {
return getResourceAsStream(resource, getClassLoaders(null));
}
/**
* Get a resource from the classpath, starting with a specific class loader
*
* @param resource - the resource to find
* @param classLoader - the first class loader to try
* @return the stream or null
*/
public InputStream getResourceAsStream(String resource, ClassLoader classLoader) {
return getResourceAsStream(resource, getClassLoaders(classLoader));
}
/**
* Find a class on the classpath (or die trying)
*
* @param name - the class to look for
* @return - the class
* @throws ClassNotFoundException Duh.
*/
public Class<?> classForName(String name) throws ClassNotFoundException {
return classForName(name, getClassLoaders(null));
}
/**
* Find a class on the classpath, starting with a specific classloader (or die trying)
*
* @param name - the class to look for
* @param classLoader - the first classloader to try
* @return - the class
* @throws ClassNotFoundException Duh.
*/
public Class<?> classForName(String name, ClassLoader classLoader) throws ClassNotFoundException {
return classForName(name, getClassLoaders(classLoader));
}
/**
* Try to get a resource from a group of classloaders
*
* @param resource - the resource to get
* @param classLoader - the classloaders to examine
* @return the resource or null
*/
InputStream getResourceAsStream(String resource, ClassLoader[] classLoader) {
//ClassLoader包含以下5种
for (ClassLoader cl : classLoader) {
if (null != cl) {
// try to find the resource as passed(尝试通过提供路径进行加载)
InputStream returnValue = cl.getResourceAsStream(resource);
// now, some class loaders want this leading "/", so we'll add it and try again if we didn't find the resource(现在,一些类加载器需要这个前导“/”,所以我们将添加它,如果找不到资源,请重试)
if (null == returnValue) {
returnValue = cl.getResourceAsStream("/" + resource);
}
if (null != returnValue) {
return returnValue;
}
}
}
return null;
}
//
ClassLoader[] getClassLoaders(ClassLoader classLoader) {
return new ClassLoader[]{
classLoader,//加载资源时,提供的加载器
defaultClassLoader,//系统默认的加载器(需通过静态方法设置否则默认为null)
Thread.currentThread().getContextClassLoader(),//当前线程的类加载器
getClass().getClassLoader(),//当前Resources的类加载器
systemClassLoader};//系统默认的类加载器
}
/**
* Get a resource as a URL using the current class path
*
* @param resource - the resource to locate
* @param classLoader - the class loaders to examine
* @return the resource or null
*/
URL getResourceAsURL(String resource, ClassLoader[] classLoader) {
URL url;
for (ClassLoader cl : classLoader) {
if (null != cl) {
// look for the resource as passed in...
url = cl.getResource(resource);
// ...but some class loaders want this leading "/", so we'll add it
// and try again if we didn't find the resource
if (null == url) {
url = cl.getResource("/" + resource);
}
// "It's always in the last place I look for it!"
// ... because only an idiot would keep looking for it after finding it, so stop looking already.
if (null != url) {
return url;
}
}
}
// didn't find it anywhere.
return null;
}
/**
* Attempt to load a class from a group of classloaders
*
* @param name - the class to load
* @param classLoader - the group of classloaders to examine
* @return the class
* @throws ClassNotFoundException - Remember the wisdom of Judge Smails: Well, the world needs ditch diggers, too.
*/
Class<?> classForName(String name, ClassLoader[] classLoader) throws ClassNotFoundException {
for (ClassLoader cl : classLoader) {
if (null != cl) {
try {
return Class.forName(name, true, cl);
} catch (ClassNotFoundException e) {
// we'll ignore this until all classloaders fail to locate the class
}
}
}
throw new ClassNotFoundException("Cannot find class: " + name);
}
}