parent
55b471ddf7
commit
b30d43466f
@ -0,0 +1,278 @@
|
||||
# DefaultSingletonBeanRegistry
|
||||
- Author: [HuiFer](https://github.com/huifer)
|
||||
- 源码阅读仓库: [huifer-spring](https://github.com/huifer/spring-framework-read)
|
||||
- 源码路径: `org.springframework.beans.factory.support.DefaultSingletonBeanRegistry`
|
||||
- 官方提供的测试类: `org.springframework.beans.factory.support.DefaultSingletonBeanRegistryTests`
|
||||
|
||||
类图
|
||||
![image-20200110093044672](/images/spring/image-20200110093044672.png)
|
||||
## 注册方法解析
|
||||
- 从名字可以看出这是一个单例对象的注册类
|
||||
- `org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.registerSingleton`
|
||||
|
||||
|
||||
|
||||
- 测试用例出发
|
||||
|
||||
```java
|
||||
@Test
|
||||
public void testSingletons() {
|
||||
DefaultSingletonBeanRegistry beanRegistry = new DefaultSingletonBeanRegistry();
|
||||
|
||||
TestBean tb = new TestBean();
|
||||
beanRegistry.registerSingleton("tb", tb);
|
||||
assertSame(tb, beanRegistry.getSingleton("tb"));
|
||||
|
||||
TestBean tb2 = (TestBean) beanRegistry.getSingleton("tb2", new ObjectFactory<Object>() {
|
||||
@Override
|
||||
public Object getObject() throws BeansException {
|
||||
return new TestBean();
|
||||
}
|
||||
});
|
||||
assertSame(tb2, beanRegistry.getSingleton("tb2"));
|
||||
|
||||
assertSame(tb, beanRegistry.getSingleton("tb"));
|
||||
assertSame(tb2, beanRegistry.getSingleton("tb2"));
|
||||
assertEquals(2, beanRegistry.getSingletonCount());
|
||||
String[] names = beanRegistry.getSingletonNames();
|
||||
assertEquals(2, names.length);
|
||||
assertEquals("tb", names[0]);
|
||||
assertEquals("tb2", names[1]);
|
||||
|
||||
beanRegistry.destroySingletons();
|
||||
assertEquals(0, beanRegistry.getSingletonCount());
|
||||
assertEquals(0, beanRegistry.getSingletonNames().length);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
- 第一个关注的方法`org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#registerSingleton` 注册单例对象
|
||||
|
||||
```java
|
||||
/**
|
||||
* 注册一个单例对象
|
||||
*
|
||||
* @param beanName the name of the bean
|
||||
* @param singletonObject the existing singleton object
|
||||
* @throws IllegalStateException
|
||||
*/
|
||||
@Override
|
||||
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
|
||||
Assert.notNull(beanName, "Bean name must not be null");
|
||||
Assert.notNull(singletonObject, "Singleton object must not be null");
|
||||
synchronized (this.singletonObjects) {
|
||||
// 通过beanName获取单例对象
|
||||
Object oldObject = this.singletonObjects.get(beanName);
|
||||
// 不为空异常
|
||||
if (oldObject != null) {
|
||||
throw new IllegalStateException("Could not register object [" + singletonObject +
|
||||
"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
|
||||
}
|
||||
// 添加方法
|
||||
addSingleton(beanName, singletonObject);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
```java
|
||||
/**
|
||||
* Add the given singleton object to the singleton cache of this factory.
|
||||
* <p>To be called for eager registration of singletons.
|
||||
* <p>
|
||||
* 添加单例对象的操作方法
|
||||
*
|
||||
* @param beanName the name of the bean
|
||||
* @param singletonObject the singleton object
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
```
|
||||
- 这些变量是什么
|
||||
```java
|
||||
/**
|
||||
* 单例对象的缓存: beanName -> Object
|
||||
*/
|
||||
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
|
||||
|
||||
/**
|
||||
* 单例工厂的缓存: beanName -> ObjectFactory。
|
||||
*/
|
||||
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
|
||||
|
||||
/**
|
||||
* 延迟加载的单例对象缓存: beanName -> Object
|
||||
*/
|
||||
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
|
||||
|
||||
/**
|
||||
* 已经注册过的单例对象名称(beanName)
|
||||
*/
|
||||
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
|
||||
|
||||
/**
|
||||
* 当前正在创建的单例对象名称(beanName)
|
||||
*/
|
||||
private final Set<String> singletonsCurrentlyInCreation =
|
||||
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
|
||||
|
||||
private final Set<String> inCreationCheckExclusions =
|
||||
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
|
||||
/**
|
||||
* 摧毁单例对象
|
||||
*/
|
||||
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
|
||||
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
|
||||
/**
|
||||
* bean 和beanName的关系
|
||||
*/
|
||||
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
|
||||
/**
|
||||
* bean 依赖关系 beanName -> 依赖关系
|
||||
*/
|
||||
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
|
||||
/**
|
||||
* 异常列表
|
||||
*/
|
||||
@Nullable
|
||||
private Set<Exception> suppressedExceptions;
|
||||
/**
|
||||
* 标记是否在 destroySingletons 上
|
||||
*/
|
||||
private boolean singletonsCurrentlyInDestruction = false;
|
||||
|
||||
```
|
||||
|
||||
- 注册方法至此结束
|
||||
|
||||
## 获取方法解析
|
||||
- `org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(java.lang.String)`
|
||||
```java
|
||||
@Override
|
||||
@Nullable
|
||||
public Object getSingleton(String beanName) {
|
||||
return getSingleton(beanName, true);
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
@Nullable
|
||||
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
|
||||
// 从列表中获取单例对象
|
||||
Object singletonObject = this.singletonObjects.get(beanName);
|
||||
// 判断当前beanName是否存在
|
||||
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
|
||||
synchronized (this.singletonObjects) {
|
||||
// 从延迟加载中获取
|
||||
singletonObject = this.earlySingletonObjects.get(beanName);
|
||||
if (singletonObject == null && allowEarlyReference) {
|
||||
// 从singletonFactories获取ObjectFactory
|
||||
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
|
||||
if (singletonFactory != null) {
|
||||
// 获取对象
|
||||
singletonObject = singletonFactory.getObject();
|
||||
// 加入缓存
|
||||
this.earlySingletonObjects.put(beanName, singletonObject);
|
||||
this.singletonFactories.remove(beanName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return singletonObject;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
- 获取单例对象的本质就是从map中获取 ObjectFactory 进而执行 getObject()
|
||||
`ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);`
|
||||
- 测试方法
|
||||
```java
|
||||
|
||||
TestBean tb2 = (TestBean) beanRegistry.getSingleton("tb2", new ObjectFactory<Object>() {
|
||||
@Override
|
||||
public Object getObject() throws BeansException {
|
||||
return new TestBean();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
- 获取单例对象的方式
|
||||
|
||||
```java
|
||||
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) {
|
||||
// Has the singleton object implicitly appeared in the meantime ->
|
||||
// if yes, proceed with it since the exception indicates that state.
|
||||
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;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
不难发现最后都是通过`singletonObject = singletonFactory.getObject();`进行获取
|
||||
|
||||
这个地方的方法实际上就是测试类中的
|
||||
|
||||
```java
|
||||
new ObjectFactory<Object>() {
|
||||
@Override
|
||||
public Object getObject() throws BeansException {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
通过`getObject`就可以获取当前对象
|
After Width: | Height: | Size: 13 KiB |
Loading…
Reference in new issue