Spring源码分析系列
Spring源码分析-启动流程浅析 Spring源码分析-Spring源码分析-BeanDefinition Spring源码分析-Bean生命周期概述 Spring源码分析-Bean生命周期查找与注册 Spring源码分析-Bean生命周期查找与注册(2)
前言
bean的生命周期是重要的知识点,为了能记住这几篇博客都会反复提醒,具体如下: 实例化 --> 属性赋值 --> Bean后置处理器before方法 --> 属性处理器afterProtpertiesSet --> 初始化方法init-method --> Bean后置处理器after方法 --> 对象应用 --> 销毁方法destroy-method --> gc回收。 本篇博客将进一步分析,bean获取与注册流程
一、getBean
spring一共提供三个getBean重载方法,具体声明如下
public Object getSingleton(String beanName)
protected Object getSingleton(String beanName, boolean allowEarlyReference)
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory)
前两个只用于查找,第三个可以用于注册
1.1、查找
下面的代码注释很详细,分别从一级缓存,二级缓存,三级缓存中进行查找,直到找到为止
@Override
@Nullable
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
1.2、注册
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
注意方法的第二个参数是一个lamda表达式,lamda表达式内容如下:
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
创建完bean对象,要将bean插入到一级缓存,并且从二级,三级缓存中移除掉
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
二、getObjectForBeanInstance
当我们从缓存中获取到bean对象,这个bean对象可能是FactoryBean,并不是我们实际要用的对象
2.1、源码
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName,
@Nullable RootBeanDefinition mbd) {
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
2.2、例子
spring代码大部分接口都自己的抽象类,我们可以直接继承抽象类,并将其注入到spring ioc容器中
@Component
public class FactoryBeanUser extends AbstractFactoryBean<User> {
@Override
public Class<?> getObjectType() {
return User.class;
}
@Override
protected User createInstance() throws Exception {
User user = new User();
user.setUsername("xuxb");
return user;
}
}
上面创建一个FactoryBean并且注入到spring容器中,接下来获取一下这个bean:
public static void main(String[] args) {
try {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.worker");
Object o1 = context.getBean("factoryBeanUser");
System.out.println("o1="+o1);
Object o2 = context.getBean("factoryBeanUser");
System.out.println("o2="+o2);
context.registerShutdownHook();
} catch (Exception e) {
System.out.println(e);
}
}
输出内容
> Task :spring-study-01:WApp.main()
o1=com.worker.User@10a035a0
o2=com.worker.User@10a035a0
BUILD SUCCESSFUL in 6s
从上面内容可知 1、注入的类型的是FactoryBeanUser,而得到的类型是User 2、每次获取bean对象都是同一个(地址相同),第一次创建成功后就缓存起来了
三、总结
本篇博客,介绍了getBean方法处理逻辑,它是spring框架中一个核心代码,理解它有助于理解spring对bean的管理方式。
|