publicabstractclassAbstractBeanDefinitionextendsBeanMetadataAttributeAccessor implementsBeanDefinition, Cloneable { /** * Constant for the default scope name: {@code ""}, equivalent to singleton * status unless overridden from a parent bean definition (if applicable). */ publicstaticfinalStringSCOPE_DEFAULT=""; @Nullable privateStringscope= SCOPE_DEFAULT; /** * Return whether this a <b>Singleton</b>, with a single shared instance * returned from all calls. * @see #SCOPE_SINGLETON */ @Override publicbooleanisSingleton() { // "singleton".equals(this.scope) || "".equals(this.scope) return SCOPE_SINGLETON.equals(this.scope) || SCOPE_DEFAULT.equals(this.scope); }
/** * Return whether this a <b>Prototype</b>, with an independent instance * returned for each call. * @see #SCOPE_PROTOTYPE */ @Override publicbooleanisPrototype() { // "prototype".equals(this.scope) return SCOPE_PROTOTYPE.equals(this.scope); } }
@Override public Object get(String name, ObjectFactory<?> objectFactory) { // 获取RequestAttributes对象 RequestAttributesattributes= RequestContextHolder.currentRequestAttributes(); // 从RequestAttributes对象中获取name对应的bean实例,这里getAttribute方法中根据传入的第二个参数getScope()做不同的处理 ObjectscopedObject= attributes.getAttribute(name, getScope()); if (scopedObject == null) { // 如果bean对象还不存在,则从对象工厂objectFactory中获取 scopedObject = objectFactory.getObject(); // 存储创建好的bean对象,setAttribute方法会根据传入的getScope()值做不同处理 attributes.setAttribute(name, scopedObject, getScope()); // Retrieve object again, registering it for implicit session attribute updates. // As a bonus, we also allow for potential decoration at the getAttribute level. ObjectretrievedObject= attributes.getAttribute(name, getScope()); if (retrievedObject != null) { // Only proceed with retrieved object if still present (the expected case). // If it disappeared concurrently, we return our locally created instance. scopedObject = retrievedObject; } } }
/** * 模板方法设计模式的体现 * * Template method that determines the actual target scope. * @return the target scope, in the form of an appropriate * {@link RequestAttributes} constant * @see RequestAttributes#SCOPE_REQUEST * @see RequestAttributes#SCOPE_SESSION */ protectedabstractintgetScope();
// InheritableThreadLocal privatestaticfinal ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder = newNamedInheritableThreadLocal<>("Request context"); @Nullable publicstatic RequestAttributes getRequestAttributes() { // 先从ThreadLocal中获取,为null再从InheritableThreadLocal中获取 RequestAttributesattributes= requestAttributesHolder.get(); if (attributes == null) { attributes = inheritableRequestAttributesHolder.get(); } return attributes; } publicstatic RequestAttributes currentRequestAttributes()throws IllegalStateException { // 获取和当前线程绑定的RequestAttributes对象 RequestAttributesattributes= getRequestAttributes(); if (attributes == null) {// if (jsfPresent) { attributes = FacesRequestAttributesFactory.getFacesRequestAttributes(); } if (attributes == null) { thrownewIllegalStateException("No thread-bound request found: " + "Are you referring to request attributes outside of an actual web request, " + "or processing a request outside of the originally receiving thread? " + "If you are actually operating within a web request and still receive this message, " + "your code is probably running outside of DispatcherServlet: " + "In this case, use RequestContextListener or RequestContextFilter to expose the current request."); } } return attributes; } }