`
michael.softtech
  • 浏览: 208806 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

spring源码分析之——spring scope的实现原理

阅读更多

大家都知道spring中的bean是有生命周期的,比如:singleton,prototype,session,request,globalsession.

那么这些生命周期是如何实现的呢?

 

继续前面章节的分析,回到AbstractBeanFactory中对bean的获取代码上面来:

private <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {

		final String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isDebugEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				if (args != null) {
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}

			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			checkMergedBeanDefinition(mbd, beanName, args);

			// Guarantee initialization of beans that the current bean depends on.
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				for (String dependsOnBean : dependsOn) {
					getBean(dependsOnBean);
					registerDependentBean(dependsOnBean, beanName);
				}
			}

			// Create bean instance.
			if (mbd.isSingleton()) {
				sharedInstance = getSingleton(beanName, new ObjectFactory() {
					public Object getObject() throws BeansException {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					}
				});
				bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}

			else if (mbd.isPrototype()) {
				// It's a prototype -> create a new instance.
				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 '" + scopeName + "'");
				}
				try {
					Object scopedInstance = scope.get(beanName, new ObjectFactory() {
						public Object getObject() throws BeansException {
							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);
				}
			}
		}

		// Check if required type matches the type of the actual bean instance.
		if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
			throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
		}
		return (T) bean;
	}

   可见,当bean的scope是prototype的时候,直接创建一个新object.这个object用完自然也就回收了,没啥好说的。

            当bean的scope是singleton的时候,在DefaultSingletonBeanRegistry下面有一个map负责维护singleton   bean的缓存。生命周期就是容器的生命周期。

 

  最后到了非prototype,非singleton的情况。

  这种情况下需要从scope里面获取。

 

   在当前线程下面有一个绑定的RequestAttributes,scope就是通过这个RequestAttributes来获取维护的bean的信息。查看一下这个接口的实现类:ServletRequestAttributes,里面的getAttribute方法实现了对bean的获取:

 

public Object getAttribute(String name, int scope) {
		if (scope == SCOPE_REQUEST) {
			if (!isRequestActive()) {
				throw new IllegalStateException(
						"Cannot ask for request attribute - request is not active anymore!");
			}
			return this.request.getAttribute(name);
		}
		else {
			HttpSession session = getSession(false);
			if (session != null) {
				try {
					Object value = session.getAttribute(name);
					if (value != null) {
						synchronized (this.sessionAttributesToUpdate) {
							this.sessionAttributesToUpdate.put(name, value);
						}
					}
					return value;
				}
				catch (IllegalStateException ex) {
					// Session invalidated - shouldn't usually happen.
				}
			}
			return null;
		}
	}

    可见,当scope是requestscope的时候,bean建立之后放在request里面,需要时取出。

             当scopde是sessionscope/globalsessionscope的时候,bean建立之后放在session/globalsession里面,需要时取出。

 

 

 

分享到:
评论

相关推荐

    二、Spring源码分析——BeanFactory

    《Spring源码分析——BeanFactory》 在Java的IoC(Inversion of Control)和DI(Dependency Injection)领域,Spring框架扮演着至关重要的角色。BeanFactory是Spring的核心组件之一,它是容器的基石,负责管理应用...

    五、Spring源码分析——Spring Aop

    《Spring AOP 源码分析》 在深入探讨Spring AOP之前,我们先要理解AOP(面向切面编程)的基本概念。AOP是一种编程范式,它将关注点分离,使得我们可以将横切关注点(如日志、事务管理、安全检查等)与业务逻辑解耦...

    Spring源码分析.pdf

    在 Spring 框架中,IOC 容器扮演着核心角色,本文将深入分析 Spring 源码,了解 IOC 容器的实现机制和基本原理。 一、IOC 容器 IOC容器是 Spring 框架的核心组件之一,它提供了一个统一的方式来管理应用程序中的...

    三、Spring源码分析——ApplicationContext

    《Spring源码分析——ApplicationContext》 在Java世界中,Spring框架是不可或缺的一部分,它以其强大的IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)特性,极大地...

    四、Spring源码分析——动态代理

    分析Spring源码有助于深入理解其动态代理的工作原理。例如,可以查看`org.springframework.aop.framework.JdkDynamicAopProxy`和`org.springframework.aop.framework.CglibAopProxy`这两个类,它们分别实现了JDK和...

    spring源码分析(1-10)

    Spring 源代码分析系列涵盖了多个关键模块,包括事务处理、IoC容器、JDBC、MVC、AOP以及与Hibernate和Acegi安全框架的集成。以下是对这些知识点的详细阐述: 1. **Spring 事务处理**:Spring 提供了声明式事务管理...

    Spring5 源码分析(第 2 版) .zip

    总的来说,《Spring5 源码分析(第 2 版)》这本书不仅涵盖了Spring5的主要特性和组件,还深入探讨了其实现原理,是Java开发者深入理解Spring框架、提升技术水平的宝贵资源。通过对书中源码的阅读和理解,读者可以更好...

    Spring5 源码分析(第 2 版)-某Tom老师

    Spring作为Java领域最为广泛应用的框架之一,其源码的深入理解对于开发者来说至关重要。这篇文档通过详细剖析Spring5的源码,将复杂的概念以深入浅出的方式呈现出来,让学习者能够更好地掌握Spring的内在工作原理。 ...

    spring 源码中文注释

    在源码分析的过程中,读者会深入理解Spring的内部工作机制,例如如何解析配置、如何创建bean实例、如何实现AOP代理等。这将有助于开发者编写更高效、更健壮的代码,也能为参与Spring的扩展或定制打下坚实基础。 总...

    Spring源码分析.txt

    spring源码分析,百度云视频。链接如果失效了,请私聊我。

    spring源码分析专题学习资源

    spring源码分析专题,源码分析视频,对spring的源码进行分析

    Spring源码分析_Spring_IOC

    ### Spring源码分析_Spring_IOC:深入理解Spring的IOC容器机制 #### 基本概念与核心作用 在探讨Spring框架的核心组件之一——IOC(Inversion of Control,控制反转)容器之前,首先需要理解它在Spring框架中的角色...

    spring源码阅读——1.spring-core-3.2.9

    阅读Spring Core的源码可以帮助我们更深入地理解其工作原理,提高解决问题的能力。通过分析`readme.txt`,我们可以获得关于这个版本的更多细节,例如新特性、已知问题和改进之处。同时,了解XML配置文件的结构和作用...

    Tom_深入分析Spring源码

    Spring作为Java领域中最重要的轻量级应用框架之一,它的设计理念、实现方式以及工作原理对于任何想成为优秀Java开发者的人都至关重要。Tom老师的讲解无疑为我们揭示了Spring背后的神秘面纱,帮助我们更好地理解和...

    Spring 源码分析文档----自用

    ### Spring 源码分析——设计模式篇 #### 一、引言 Spring框架作为Java企业级开发领域中不可或缺的一部分,其内部集成了多种设计模式,不仅有助于提高系统的可维护性和扩展性,还能够帮助开发者更好地理解和应用...

    spring源码注释中文

    Spring 源码注释中文版的提供,使得开发者能够更加深入地理解 Spring 的工作原理,无需经过复杂的编译过程,可以直接阅读源码注释来学习。 Spring 框架主要由以下几个关键模块组成: 1. **Core Container(核心...

    spring源码分析

    《Spring源码分析》 Spring框架作为Java领域中不可或缺的一部分,其强大之处在于它提供了丰富的功能,包括依赖注入(Dependency Injection,简称DI)、面向切面编程(Aspect-Oriented Programming,简称AOP)、事务...

    Spring源码分析.rar

    这份"Spring源码分析"资料深入探讨了Spring的核心机制,帮助我们理解其背后的原理,从而更好地应用和优化Spring框架。 Spring的核心特性包括依赖注入(Dependency Injection, DI)、面向切面编程(Aspect-Oriented ...

    Spring技术内幕:深入解析Spring架构与设计原理.pdf

    Spring技术内幕:深入解析Spring架构与设计原理 Spring技术内幕 Spring是一个基于Java的开源框架,旨在简化Java企业应用的开发。Spring的目标是提供一个简洁、灵活、可扩展的框架,以帮助开发者快速构建企业级...

Global site tag (gtag.js) - Google Analytics