Spring源码解析之资源与工厂创建流程解析

导读:本篇文章讲解 Spring源码解析之资源与工厂创建流程解析,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

前文

Spring源码解析之bean的创建与获取对springbean的加载有了一个初步的了解,接下来我们要做的就是对内部源码进行更深度的剖析!

资源解析的分析

Resource resource = new ClassPathResource("spring-config.xml");

我们对ClassPathResource进行探究:

	//这个构造方法调用了带有ClassLoader的构造方法,默认传了个null
	public ClassPathResource(String path) {
		this(path, (ClassLoader) null);
	}

调用的具体构造:

	/**
	 * 为使用{@code ClassLoader}创建一个新的{@code ClassPathResource}。
	 * 将删除一个前斜杠,因为ClassLoader资源访问*方法将不接受它。
	 *
	 * Create a new {@code ClassPathResource} for {@code ClassLoader} usage.
	 * A leading slash will be removed, as the ClassLoader resource access
	 * methods will not accept it.
	 * @param path the absolute path within the classpath
	 * @param classLoader the class loader to load the resource with,
	 * or {@code null} for the thread context class loader
	 * @see ClassLoader#getResourceAsStream(String)
	 */
	public ClassPathResource(String path, @Nullable ClassLoader classLoader) {
		Assert.notNull(path, "Path must not be null");
		String pathToUse = StringUtils.cleanPath(path);
		//如果这个路径以斜杠开头,就把斜杠给去了
		if (pathToUse.startsWith("/")) {
			pathToUse = pathToUse.substring(1);
		}
		this.path = pathToUse;
		//如果传了classLoader,就把classLoader传给当前的classLoader,没传的话,就给个默认的
		this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
	}

这里我对源码中注释的翻译使用的是idea的插件Translation,翻译非常好用,安利一波~~
我们开始分析:
一、首先看他的cleanPath方法,我们知道这是Spring讲五花八门的路径,通过各种校验转换成合法的路径!
二、去除斜杠,源码注释说的明明白白,ClassLoader资源访问方法将不接受它,这里的它就是指斜杠!
三、给path和classLoader赋值,这里面是个三元表达式,如果不为空的话,就传进当前的classLoader。我们再看看ClassUtils.getDefaultClassLoader()

	@Nullable
	public static ClassLoader getDefaultClassLoader() {
		ClassLoader cl = null;
		try {
			//获取当前线程的上下文类加载器
			cl = Thread.currentThread().getContextClassLoader();
		}
		catch (Throwable ex) {
			// Cannot access thread context ClassLoader - falling back...
		}
		//补救措施
		if (cl == null) {
			// No thread context class loader -> use class loader of this class.
			//获取当前类加载器
			cl = ClassUtils.class.getClassLoader();
			if (cl == null) {
				// getClassLoader() returning null indicates the bootstrap ClassLoader
				try {
					//系统类加载器
					cl = ClassLoader.getSystemClassLoader();
				}
				catch (Throwable ex) {
					// Cannot access system ClassLoader - oh well, maybe the caller can live with null...
				}
			}
		}
		return cl;
	}

考虑的可谓不可不详细,如果没有传入ClassLoader,首先是获取当前线程的上下文类加载器,获取不到就获取当前类加载器,再不济就获取系统类加载器

到此资源加载的具体源码就分析完了,我们接着看DefaultListableBeanFactory里的源码。

先看一下DefaultListableBeanFactory类结构图:
在这里插入图片描述
我们看到DefaultListableBeanFactory是最底层的,他的顶级父类是BeanFactory,我们先看DefaultListableBeanFactory的构造方法:

	/**
	 * Create a new AbstractAutowireCapableBeanFactory.
	 * ignoreDependencyInterface:忽略给定接口的向动装配功能
	 */
	public AbstractAutowireCapableBeanFactory() {
		super();
		ignoreDependencyInterface(BeanNameAware.class);
		ignoreDependencyInterface(BeanFactoryAware.class);
		ignoreDependencyInterface(BeanClassLoaderAware.class);
		if (IN_NATIVE_IMAGE) {
			this.instantiationStrategy = new SimpleInstantiationStrategy();
		}
		else {
			this.instantiationStrategy = new CglibSubclassingInstantiationStrategy();
		}
	}

ignoreDependencyInterface

	/**
	 * Dependency interfaces to ignore on dependency check and autowire, as Set of
	 * Class objects. By default, only the BeanFactory interface is ignored.
	 */
	private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<>();
	
	//忽略掉spring提供的但又不建议使用的依赖接口对象给忽略掉
	public void ignoreDependencyInterface(Class<?> ifc) {
		this.ignoredDependencyInterfaces.add(ifc);
	}

到此为止,资源和bean工厂都准备好,但是这两者还没有关联!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/16385.html

(0)
小半的头像小半

相关推荐

半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!