本篇文章分析各个作用域的bean的获取
在这贴上整个流程代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { Object prototypeInstance = null ; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); final Scope scope = this .scopes.get(scopeName); if (scope == null ) { throw new IllegalStateException ("No Scope registered for scope name '" + scopeName + "'" ); } try { Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException (beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton" , ex); } }
1、singleton 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }
主要分为两步:
获取原始bean实例
获取真正的bean对象
1.1、getSingleton 返回在给定名称下注册的(原始)单例对象,如果还没有注册,则创建并注册一个新的单例对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 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; } }
尝试的从单例缓存中获取单例对象,如果不存在,则通过工厂创建,并注册到单例缓存中,在创建的前后分别有前后置处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 protected void beforeSingletonCreation (String beanName) { if (!this .inCreationCheckExclusions.contains(beanName) && !this .singletonsCurrentlyInCreation.add(beanName)) { throw new BeanCurrentlyInCreationException (beanName); } } protected void afterSingletonCreation (String beanName) { if (!this .inCreationCheckExclusions.contains(beanName) && !this .singletonsCurrentlyInCreation.remove(beanName)) { throw new IllegalStateException ("Singleton '" + beanName + "' isn't currently in creation" ); } }
注册单例缓存,将给定的单例对象添加到该工厂的单例缓存中。
1 2 3 4 5 6 7 8 9 10 11 12 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); } }
1.2、getObjectForBeanInstance 这个方法在尝试获取单例的时候分析过了,这边就不贴了。
2、prototype 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Object prototypeInstance = null ;try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
通过createBean获取bean原始实例。 也有前后置处理,注意prototypesCurrentlyInCreation为ThreadLocal。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 private final ThreadLocal<Object> prototypesCurrentlyInCreation = new NamedThreadLocal <>("Prototype beans currently in creation" ); @SuppressWarnings("unchecked") protected void beforePrototypeCreation (String beanName) { Object curVal = this .prototypesCurrentlyInCreation.get(); if (curVal == null ) { this .prototypesCurrentlyInCreation.set(beanName); } else if (curVal instanceof String) { Set<String> beanNameSet = new HashSet <>(2 ); beanNameSet.add((String) curVal); beanNameSet.add(beanName); this .prototypesCurrentlyInCreation.set(beanNameSet); } else { Set<String> beanNameSet = (Set<String>) curVal; beanNameSet.add(beanName); } } @SuppressWarnings("unchecked") protected void afterPrototypeCreation (String beanName) { Object curVal = this .prototypesCurrentlyInCreation.get(); if (curVal instanceof String) { this .prototypesCurrentlyInCreation.remove(); } else if (curVal instanceof Set) { Set<String> beanNameSet = (Set<String>) curVal; beanNameSet.remove(beanName); if (beanNameSet.isEmpty()) { this .prototypesCurrentlyInCreation.remove(); } } }
也含有getObjectForBeanInstance方法,看样子我应该拉出一篇文章专门分析一下。
3、request/session/global session 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 String scopeName = mbd.getScope(); final Scope scope = this .scopes.get(scopeName);if (scope == null ) { throw new IllegalStateException ("No Scope registered for scope name '" + scopeName + "'" ); } Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
主要分析scope.get()方法,这个Scope接口的抽象类AbstractRequestAttributesScope中实现了get方法,简单看看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @Override public Object get (String name, ObjectFactory<?> objectFactory) { RequestAttributes attributes = RequestContextHolder.currentRequestAttributes(); Object scopedObject = attributes.getAttribute(name, getScope()); if (scopedObject == null ) { scopedObject = objectFactory.getObject(); attributes.setAttribute(name, scopedObject, getScope()); Object retrievedObject = attributes.getAttribute(name, getScope()); if (retrievedObject != null ) { scopedObject = retrievedObject; } } return scopedObject; }
就是从RequestAttributes中获取的对象。
大体上分析完了各个scope中的bean加载,最重要的方法createBean(beanName, mbd, args)之后分析,方法getObjectForBeanInstance(scopedInstance, name, beanName, mbd)后期也想再拉出来分析一下。