Spring Bean 的定义应该可以理解为由IoC配置、实例化及管理的对象,通过 Bean Definitiion 来进行初始化。
Spring Bean 配置的常见方式
- XML 配置
- JavaConfig 配置
- 注解配置
Spring Bean 的作用域
- Singleton - 默认,每个 IoC 容器只有一个实例
- Prototype - 每次请求都会产生一个新的实例
- Request - 每一次 HTTP 请求都会产生一个新的 Bean 实例,并且该 Bean 仅在当前 HTTP 请求内有效。
- Session - 每一个的 Session 都会产生一个新的 Bean 实例,同时该 Bean 仅在当前 HTTP Session 内有效。
- Application - 每一个 Web Application 都会产生一个新的 Bean ,同时该 Bean 仅在当前 Web Application 内有效。
当且仅当为 web 的ApplicationContext的时候后三者才有效。
Spring Bean 的生命周期管理
举例通过 Xml配置文件来梳理流程。
ClassPathResource resource = new ClassPathResource("...");
DefaultListenableFactory factory = new DefaultListenableFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(dlf);
reader.loadBeanDefinitions(resource);
Resource -> XmlFactory -> XmlBeanDefinitialReader -> XmlBeanDefinitialReader#loadBeanDefinitions 来进行Bean 的初始化。
那么其中的 Bean 是如何进行存放的呢?从最后一个调用函数 loadBeanDefinitions(resource) 分析:
加载关键逻辑代码
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return this.loadBeanDefinitions(new EncodedResource(resource));
}
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (this.logger.isTraceEnabled()) {
this.logger.trace("Loading XML bean definitions from " + encodedResource);
}
Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if (!((Set)currentResources).add(encodedResource)) {
throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
} else {
int var5;
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
} finally {
inputStream.close();
}
} catch (IOException var15) {
throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var15);
} finally {
((Set)currentResources).remove(encodedResource);
if (((Set)currentResources).isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
return var5;
}
}
参考链接列表:
【死磕 Spring】—– IOC 之 加载 Bean
Spring源码阅读——ClassPathXmlApplicationContext(三)