DefaultSingletonBeanRegistry

  • Author: HuiFer
  • 源码阅读仓库: SourceHot-Spring
  • 源码路径: org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
  • 官方提供的测试类: org.springframework.beans.factory.support.DefaultSingletonBeanRegistryTests

类图 image-20200110093044672

注册方法解析

  • 从名字可以看出这是一个单例对象的注册类
  • org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.registerSingleton

  • 测试用例出发

    1. @Test
    2. public void testSingletons() {
    3. DefaultSingletonBeanRegistry beanRegistry = new DefaultSingletonBeanRegistry();
    4. TestBean tb = new TestBean();
    5. beanRegistry.registerSingleton("tb", tb);
    6. assertSame(tb, beanRegistry.getSingleton("tb"));
    7. TestBean tb2 = (TestBean) beanRegistry.getSingleton("tb2", new ObjectFactory<Object>() {
    8. @Override
    9. public Object getObject() throws BeansException {
    10. return new TestBean();
    11. }
    12. });
    13. assertSame(tb2, beanRegistry.getSingleton("tb2"));
    14. assertSame(tb, beanRegistry.getSingleton("tb"));
    15. assertSame(tb2, beanRegistry.getSingleton("tb2"));
    16. assertEquals(2, beanRegistry.getSingletonCount());
    17. String[] names = beanRegistry.getSingletonNames();
    18. assertEquals(2, names.length);
    19. assertEquals("tb", names[0]);
    20. assertEquals("tb2", names[1]);
    21. beanRegistry.destroySingletons();
    22. assertEquals(0, beanRegistry.getSingletonCount());
    23. assertEquals(0, beanRegistry.getSingletonNames().length);
    24. }
  • 第一个关注的方法org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#registerSingleton 注册单例对象

  1. /**
  2. * 注册一个单例对象
  3. *
  4. * @param beanName the name of the bean
  5. * @param singletonObject the existing singleton object
  6. * @throws IllegalStateException
  7. */
  8. @Override
  9. public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
  10. Assert.notNull(beanName, "Bean name must not be null");
  11. Assert.notNull(singletonObject, "Singleton object must not be null");
  12. synchronized (this.singletonObjects) {
  13. // 通过beanName获取单例对象
  14. Object oldObject = this.singletonObjects.get(beanName);
  15. // 不为空异常
  16. if (oldObject != null) {
  17. throw new IllegalStateException("Could not register object [" + singletonObject +
  18. "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
  19. }
  20. // 添加方法
  21. addSingleton(beanName, singletonObject);
  22. }
  23. }
  1. /**
  2. * Add the given singleton object to the singleton cache of this factory.
  3. * <p>To be called for eager registration of singletons.
  4. * <p>
  5. * 添加单例对象的操作方法
  6. *
  7. * @param beanName the name of the bean
  8. * @param singletonObject the singleton object
  9. */
  10. protected void addSingleton(String beanName, Object singletonObject) {
  11. synchronized (this.singletonObjects) {
  12. this.singletonObjects.put(beanName, singletonObject);
  13. this.singletonFactories.remove(beanName);
  14. this.earlySingletonObjects.remove(beanName);
  15. this.registeredSingletons.add(beanName);
  16. }
  17. }
  • 这些变量是什么
  1. /**
  2. * 单例对象的缓存: beanName -> Object
  3. */
  4. private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
  5. /**
  6. * 单例工厂的缓存: beanName -> ObjectFactory。
  7. */
  8. private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
  9. /**
  10. * 延迟加载的单例对象缓存: beanName -> Object
  11. */
  12. private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
  13. /**
  14. * 已经注册过的单例对象名称(beanName)
  15. */
  16. private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
  17. /**
  18. * 当前正在创建的单例对象名称(beanName)
  19. */
  20. private final Set<String> singletonsCurrentlyInCreation =
  21. Collections.newSetFromMap(new ConcurrentHashMap<>(16));
  22. private final Set<String> inCreationCheckExclusions =
  23. Collections.newSetFromMap(new ConcurrentHashMap<>(16));
  24. /**
  25. * 摧毁单例对象
  26. */
  27. private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
  28. private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
  29. /**
  30. * bean 和beanName的关系
  31. */
  32. private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
  33. /**
  34. * bean 依赖关系 beanName -> 依赖关系
  35. */
  36. private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
  37. /**
  38. * 异常列表
  39. */
  40. @Nullable
  41. private Set<Exception> suppressedExceptions;
  42. /**
  43. * 标记是否在 destroySingletons 上
  44. */
  45. private boolean singletonsCurrentlyInDestruction = false;
  • 注册方法至此结束

获取方法解析

  • org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(java.lang.String)
  1. @Override
  2. @Nullable
  3. public Object getSingleton(String beanName) {
  4. return getSingleton(beanName, true);
  5. }
  1. @Nullable
  2. protected Object getSingleton(String beanName, boolean allowEarlyReference) {
  3. // 从列表中获取单例对象
  4. Object singletonObject = this.singletonObjects.get(beanName);
  5. // 判断当前beanName是否存在
  6. if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
  7. synchronized (this.singletonObjects) {
  8. // 从延迟加载中获取
  9. singletonObject = this.earlySingletonObjects.get(beanName);
  10. if (singletonObject == null && allowEarlyReference) {
  11. // 从singletonFactories获取ObjectFactory
  12. ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
  13. if (singletonFactory != null) {
  14. // 获取对象
  15. singletonObject = singletonFactory.getObject();
  16. // 加入缓存
  17. this.earlySingletonObjects.put(beanName, singletonObject);
  18. this.singletonFactories.remove(beanName);
  19. }
  20. }
  21. }
  22. }
  23. return singletonObject;
  24. }
  • 获取单例对象的本质就是从 map 中获取 ObjectFactory 进而执行 getObject() ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
  • 测试方法
  1. TestBean tb2 = (TestBean) beanRegistry.getSingleton("tb2", new ObjectFactory<Object>() {
  2. @Override
  3. public Object getObject() throws BeansException {
  4. return new TestBean();
  5. }
  6. });
  • 获取单例对象的方式
  1. public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
  2. Assert.notNull(beanName, "Bean name must not be null");
  3. synchronized (this.singletonObjects) {
  4. // 从单例对象中获取一个对象
  5. Object singletonObject = this.singletonObjects.get(beanName);
  6. if (singletonObject == null) {
  7. if (this.singletonsCurrentlyInDestruction) {
  8. throw new BeanCreationNotAllowedException(beanName,
  9. "Singleton bean creation not allowed while singletons of this factory are in destruction " +
  10. "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
  11. }
  12. if (logger.isDebugEnabled()) {
  13. logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
  14. }
  15. beforeSingletonCreation(beanName);
  16. boolean newSingleton = false;
  17. boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
  18. if (recordSuppressedExceptions) {
  19. this.suppressedExceptions = new LinkedHashSet<>();
  20. }
  21. try {
  22. // 调用自定义实现,或者接口实现
  23. singletonObject = singletonFactory.getObject();
  24. newSingleton = true;
  25. }
  26. catch (IllegalStateException ex) {
  27. // Has the singleton object implicitly appeared in the meantime ->
  28. // if yes, proceed with it since the exception indicates that state.
  29. singletonObject = this.singletonObjects.get(beanName);
  30. if (singletonObject == null) {
  31. throw ex;
  32. }
  33. }
  34. catch (BeanCreationException ex) {
  35. if (recordSuppressedExceptions) {
  36. for (Exception suppressedException : this.suppressedExceptions) {
  37. ex.addRelatedCause(suppressedException);
  38. }
  39. }
  40. throw ex;
  41. }
  42. finally {
  43. if (recordSuppressedExceptions) {
  44. this.suppressedExceptions = null;
  45. }
  46. afterSingletonCreation(beanName);
  47. }
  48. if (newSingleton) {
  49. addSingleton(beanName, singletonObject);
  50. }
  51. }
  52. return singletonObject;
  53. }
  54. }

不难发现最后都是通过singletonObject = singletonFactory.getObject();进行获取

这个地方的方法实际上就是测试类中的

  1. new ObjectFactory<Object>() {
  2. @Override
  3. public Object getObject() throws BeansException {
  4. return new TestBean();
  5. }
  6. }

通过getObject就可以获取当前对象