Spring IoC Bean-生命周期
一、什么是Spring
1、Spring IoC
a.Dependency Injection(DI)–依赖注入
b.Dependency Lookup(DL)–依赖查找
c.Spring容器管理的对象包括什么
2、Spring AOP
二、Spring Bean 生命周期概览
1、概览图
a.Spring Bean的转换过程
下面这张图演示了一个可用的Spring Bean是如何从xml配置文件中演变过来的
ps:配置元信息来源不仅可以在xml中,也可以在properties文件里以及注解元信息。
从上面的图中,我们可以比较清楚的知道Bean的元信息 经过解析得到BeanDefinition ,然后通过InstantiationStrategy策略将Class实例化为相应的Bean实例 ,此时该Bean实例字段均为空,然后经过一系列操作将一个可用的Bean实例提供出来供我们使用,在我们使用完之后,容器销毁时,将这些资源进行释放,最终有JVM进行垃圾回收。
b.Spring Bean生命周期概览图
Spring内部IoC容器默认实现为:DefaultListableBeanFactory
Bean的生命周期与方法映射如下图所示:
三、Spring Bean生命周期核心方法
1、registerBeanDefinition-Spring Bean注册
该方法定义于BeanDefinitionRegistry接口下,由DefaultListableBeanFactory提供具体实现,流程比较简单。
其实整个注册流程最核心的一段代码就是:this.beanDefinitionMap.put(beanName, beanDefinition);将相应的BeanDefinition注册到beanDefinitionMap中。key为baneName,value为BeanDefinition
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
private boolean allowBeanDefinitionOverriding = true;
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
if (hasBeanCreationStarted()) {
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
2、getMergedBeanDefinition-Spring Bean合并
该方法定义于ConfigurableBeanFactory接口下,由AbstractBeanFactory实现(考虑层次性容器)
此方法会返回一个BeanDefinition实例,如果当前Bean有parent指定,那么会返回一个父子合并后的BeanDefinition。
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
@Override
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
String beanName = transformedBeanName(name);
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
}
return getMergedLocalBeanDefinition(beanName);
}
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null && !mbd.stale) {
return mbd;
}
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
return getMergedBeanDefinition(beanName, bd, null);
}
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
RootBeanDefinition previous = null;
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
if (mbd == null || mbd.stale) {
previous = mbd;
if (bd.getParentName() == null) {
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
mbd = new RootBeanDefinition(bd);
}
}
else {
BeanDefinition pbd;
try {
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without an AbstractBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
}
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(SCOPE_SINGLETON);
}
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
if (previous != null) {
copyRelevantMergedBeanDefinitionCaches(previous, mbd);
}
return mbd;
}
}
3、resolveBeforeInstantiation
4、createBeanInstance
5、populateBean
6、initializeBean
7、preInstantiateSingletons
8、destroyBean
|