Source Code in Java -- Spring IOC - II

简单来说 IoC 容器的初始化是由 refresh() 方法启动的,这个方法标志着 IoC 容器正式启动。具体来说这个启动包括 BeanDefinition 的 Resource 定位、载入和注册三个基本过程。

关于这段话我首先不能理解的就是无缘无故出来的这个BeanDefinition,我在浏览这些源码的时候也没看到。因此,为了好好了解 Spring IoC,我还需要进一步查看内部源码和解释。

What is BeanDefinition?

对 IoC 来说,BeanDefinition 就是对依赖反转模式中管理的对象依赖关系的数据抽象。
Spring 通过定义 BeanDefinition 来管理基于 Spring 的应用中的各种对象以及它们之间的相互依赖关系。BeanDefinition 抽象了我们对 Bean 的定义,是让容器起作用的主要数据类型。

我的理解 BeanDefinition 有点像 Bean 的元数据,又有点像抽象类,又有点像 schema。

Resource location of BeanDefinition

Source Code in Java -- Spring IOC - II

再次拿出来这幅图来讲一下,像 ClassPathXmlApplicationContext 这样的方法定位资源的方式还是使用的 DefaultResourceLoader。而这个 DefaultResourceLoader 实现的是 ResourceLoader 接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public interface  {


String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;


/**
* Return a Resource handle for the specified resource.
* The handle should always be a reusable resource descriptor,
* allowing for multiple {@link Resource#getInputStream()} calls.
* <p><ul>
* <li>Must support fully qualified URLs, e.g. "file:C:/test.dat".
* <li>Must support classpath pseudo-URLs, e.g. "classpath:test.dat".
* <li>Should support relative file paths, e.g. "WEB-INF/test.dat".
* (This will be implementation-specific, typically provided by an
* ApplicationContext implementation.)
* </ul>
* <p>Note that a Resource handle does not imply an existing resource;
* you need to invoke {@link Resource#exists} to check for existence.
* @param location the resource location
* @return a corresponding Resource handle
* @see #CLASSPATH_URL_PREFIX
* @see org.springframework.core.io.Resource#exists
* @see org.springframework.core.io.Resource#getInputStream
*/
Resource getResource(String location);

/**
* Expose the ClassLoader used by this ResourceLoader.
* <p>Clients which need to access the ClassLoader directly can do so
* in a uniform manner with the ResourceLoader, rather than relying
* on the thread context ClassLoader.
* @return the ClassLoader (only {@code null} if even the system
* ClassLoader isn't accessible)
* @see org.springframework.util.ClassUtils#getDefaultClassLoader()
*/
ClassLoader getClassLoader();

}

其中 CLASSPATH_URL_PREFIX 就是 “classpath:”:

1
public static final String CLASSPATH_URL_PREFIX = "classpath:";

在 DefaultResourceLoader 中 getClassLoader 的实现如下:

1
2
3
4
5
6
7
8
9
10
/**
* Return the ClassLoader to load class path resources with.
* <p>Will get passed to ClassPathResource's constructor for all
* ClassPathResource objects created by this resource loader.
* @see ClassPathResource
*/

public ClassLoader getClassLoader() {
return (this.classLoader != null ? this.classLoader : ClassUtils.getDefaultClassLoader());
}

其中,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* Return the default ClassLoader to use: typically the thread context
* ClassLoader, if available; the ClassLoader that loaded the ClassUtils
* class will be used as fallback.
* <p>Call this method if you intend to use the thread context ClassLoader
* in a scenario where you clearly prefer a non-null ClassLoader reference:
* for example, for class path resource loading (but not necessarily for
* {@code Class.forName}, which accepts a {@code null} ClassLoader
* reference as well).
* @return the default ClassLoader (only {@code null} if even the system
* ClassLoader isn't accessible)
* @see Thread#getContextClassLoader()
* @see ClassLoader#getSystemClassLoader()
*/
public static大专栏
上一篇:幻术,一行代码实现镂空效果


下一篇:吉他谱----see you again