`
山有峰则灵
  • 浏览: 28220 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

spring IOC:AbstractBeanFactory

阅读更多
接上篇http://whoknow.iteye.com/blog/487786
DefaultSingletonBeanRegistry可以简单的管理bean但是做为一个ioc容器来讲它的功能还远远不够。比如,在一个应用中,一些bean是始终存在的,一些则是随着当前线程的结束而结束,做为一个容器来讲,它需要可以管理整个bean的生命周期

public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements ConfigurableBeanFactory {


AbstractBeanFactory继承了DefaultSingletonBeanRegistry类,并进一步丰富了已有的功能,这个类提供了singleton/prototype的选择,单例cache,对于FactoryBean的处理,bean定义的处理以及bean 的销毁…
其中比较重要的功能是对BeanFactory中getBean方法的实现
public Object getBean(String name) throws BeansException {
		return getBean(name, null, null);
	}
		
	public Object getBean(String name, Class requiredType) throws BeansException {
		return getBean(name, requiredType, null);
	}

	public Object getBean(String name, Object[] args) throws BeansException {
		return getBean(name, null, args);
	}


几个连续的重载,我们关心的是最后这个
public Object getBean(String name, Class requiredType, final Object[] args) throws BeansException {

然后一点一点看这个方法,假如给自己这样一个问题,我们首先会做什么?这个方法打算写些什么呢?
很显然,在我们的父类DefaultSingletonBeanRegistry中,已经有了一些对于bean的操作的实现,比如getSingleton方法,让我们可以拿到一个bean,于是
	Object sharedInstance = getSingleton(beanName);
	if (sharedInstance != null) {
		//一个简单的判断,先看一眼,map里是否有这个类了
		//如果有的话呢?直接返回?好像不太好,因为这个类可能是一个工厂类,所以我们还需要一个方法判断下,如果是工厂类的话,那么它应该返回一个产品
		bean = getObjectForBeanInstance(sharedInstance, name, mergedBeanDefinition);
}

看一下getObjectForBeanInstance这个方法
protected Object getObjectForBeanInstance(Object beanInstance, String name, RootBeanDefinition mbd)throws BeansException {

	//这里略去了很多代码,只是把最关键的几行取出
	if (beanInstance instanceof FactoryBean) {	
		FactoryBean factory = (FactoryBean) beanInstance;  
object = getObjectFromFactoryBean(factory, beanName, mbd);	
}	
		return object;
	}

那么这个getObjectFromFactoryBean方法又是?从参数来看,我们发现了一个factory,实际上在这个方法中会调用它
	object = factory.getObject();
         //之后
          return object


FactoryBean这个接口在DefaultSingletonBeanRegistry中的 public Object getSingleton(String beanName, ObjectFactory singletonFactory)方法中也出现过,由一个实现了FactoryBean的工厂来产生这个类

在if (sharedInstance != null) {}判断完成后,即我们当前没有这个类,接下来呢?这时该由容器将这个类实例化了,所以在}else之后
先判断是否有父容器,如果有则由父容器生产它
BeanFactory parentBeanFactory = getParentBeanFactory();
这里会调用父容器的getBean方法

如果没有则我们要创建这个类,spring在启动时首先会通过ResourceLoader读取其配置文件,然后由BeanDefinitionReader进行读取并保存到BeanDefinitionRegistry中。之后会对这些定义进行处理,这些beandefine中放置的就是xml的基本信息,如:class,scope,等等属性,结构如图:


//得到bean的定义
final RootBeanDefinition mergedBeanDefinition = getMergedBeanDefinition(beanName, false);
先拿到Bean的定义 
getMergedBeanDefinition:还是先检查是否有父容器,有就调用父容器的getMergedBeanDefinition方法,没有调用当前的
protected RootBeanDefinition getMergedBeanDefinition(String name, boolean includingAncestors)
	    throws BeansException {
		String beanName = transformedBeanName(name);
		if (includingAncestors && !containsBeanDefinition(beanName) &&
				getParentBeanFactory() instanceof AbstractBeanFactory) {
			return ((AbstractBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName, true);
		}
		return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
	}

那么getMergedBeanDefinition中呢?这里主要就是拿到它的rootbean,如果是children则调用cbd.getParentName()方法最后返回root的定义.

这里return getMergedBeanDefinition(beanName,getBeanDefinition(beanName));
getBeanDefinition是一个抽象方法
protected abstract BeanDefinition getBeanDefinition(String beanName)
由具体的子类来实现.

一个类一个责任,AbstractBeanFactory的主要职责是bean的管理,其它职责由其子类完成,如:createBean, postProcessObjectFromFactoryBean, getBeanDefinition
Spring的设计清晰易读,很大程度上都是由于类的职责划分清晰造成的。BeanFactory 是一个基本的描述,接下来我们希望这个容器可以实现上下文关系,对一个类最简单的一些操作,所以就有了SingletonBeanRegistry,HierarchicalBeanFactory接口。然后再层层向下,通过接口描述主要的组件功能,具体类进行实现

拿到这个bean的定义后,就可以实例化它了
如果是一个单例:
	if (mergedBeanDefinition.isSingleton()) {
		sharedInstance = getSingleton(beanName, new ObjectFactory() {
			public Object getObject() throws BeansException {
				try {
				//createBean由其子类AbstractAutowireCapableBeanFactory来实现
				return createBean(beanName, mergedBeanDefinition, args);
						}
						catch (BeansException ex) {
							destroySingleton(beanName);
							throw ex;
						}
					}
				});
				//这里再次判断,如果该类是一个工厂则调用其getObject()方法
bean = getObjectForBeanInstance(sharedInstance, name,mergedBeanDefinition);
			}


这里使用了一个回调方法,在父类的DefaultSingletonBeanRegistry中的public Object getSingleton(String beanName, ObjectFactory singletonFactory) 需要一个ObjectFactory,我们用一个匿名类写入方法,并调用其子类的createBean方法,在这里createBean是AbstractBeanFactory的抽象方法

如果是Prototype的话:
if (mergedBeanDefinition.isPrototype()) {
				Object prototypeInstance = null;
				try {
					beforePrototypeCreation(beanName);
					prototypeInstance = createBean(beanName, mergedBeanDefinition, args);
				}
				finally {
					afterPrototypeCreation(beanName);
				}
				// 又判断它是不是工厂类
				bean = getObjectForBeanInstance(prototypeInstance, name, mergedBeanDefinition);
			}


最后如果既不是Singleton也不是Prototype时,首先拿它的scope
String scopeName = mergedBeanDefinition.getScope();
				final Scope scope = (Scope) this.scopes.get(scopeName);
				…
				try {
				scope的get回调方法得到实例
					Object scopedInstance = scope.get(beanName, new ObjectFactory() {
						public Object getObject() throws BeansException {
							beforePrototypeCreation(beanName);
							try {
								Object bean = createBean(beanName, mergedBeanDefinition, args);
								if (requiresDestruction(bean, mergedBeanDefinition)) {
									scope.registerDestructionCallback(beanName,
											new DisposableBeanAdapter(bean, beanName, mergedBeanDefinition, getBeanPostProcessors()));
								}
								return bean;
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						}
					});
					bean = getObjectForBeanInstance(scopedInstance, name, mergedBeanDefinition);
				}
				catch (IllegalStateException ex) {
					throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active", ex);
				}


这里有一行代码
scope.registerDestructionCallback(beanName,
											new DisposableBeanAdapter(bean, beanName, mergedBeanDefinition, getBeanPostProcessors()));


注册它的销毁方法
public void registerDestructionCallback(String name, Runnable callback) {
		RequestAttributes attributes = RequestContextHolder.currentRequestAttributes();
		attributes.registerDestructionCallback(name, callback, getScope());
	}

在这里首先通过RequestContextHolder得到当前的RequestAttributes。在RequestContextHolder中requestAttributesHolder 为ThreadLocal
之后在ServletRequestAttributes注册其回调销毁方法最后
private void executeRequestDestructionCallbacks() {
		for (Iterator it = this.requestDestructionCallbacks.values().iterator(); it.hasNext();) {
			((Runnable) it.next()).run();
		}
}



可以看到在DisposableBeanAdapter中
public void run() {
		destroy();
	}

首先beanPostProcessors执行所有的DestructionAwareBeanPostProcessor,最后在最后执行invokeCustomDestroyMethod();所以客户定义的销毁方式是在最后的
	public void destroy() {
		if (this.beanPostProcessors != null) {
			if (logger.isDebugEnabled()) {
				logger.debug("Applying DestructionAwareBeanPostProcessors to bean with name '" + this.beanName + "'");
			}
			for (int i = this.beanPostProcessors.size() - 1; i >= 0; i--) {
				Object beanProcessor = this.beanPostProcessors.get(i);
				if (beanProcessor instanceof DestructionAwareBeanPostProcessor) {
					((DestructionAwareBeanPostProcessor) beanProcessor).postProcessBeforeDestruction(this.bean, this.beanName);
				}
			}
		}

		if (this.bean instanceof DisposableBean) {
			if (logger.isDebugEnabled()) {
				logger.debug("Invoking destroy() on bean with name '" + this.beanName + "'");
			}
			try {
				((DisposableBean) this.bean).destroy();
			}
			catch (Throwable ex) {
				logger.error("Couldn't invoke destroy method of bean with name '" + this.beanName + "'", ex);
			}
		}

		if (this.mergedBeanDefinition != null) {
			invokeCustomDestroyMethod();
		}
	}

分享到:
评论

相关推荐

    Spring ioc源码解读

    ### Spring IoC源码解读 #### 一、Spring IoC 容器概述 Spring框架的核心功能之一便是依赖注入(Dependency Injection, DI),而这一功能主要通过IoC容器来实现。在Spring框架中,IoC容器负责管理应用对象的生命...

    Spring源码分析_Spring_IOC

    `BeanFactory`的实现类`DefaultListableBeanFactory`与`AbstractBeanFactory`通过模板设计模式,为IOC容器的实现提供了灵活性和扩展性。 然而,在实际开发中,更常用的是`ApplicationContext`容器,它是`...

    Spring IOC设计原理解析.docx

    Spring IOC(Inversion of Control,控制反转)设计原理解析 一、什么是IOC/DI? IOC,即控制反转,是软件设计模式中的一种,它将对象的创建和管理权交给了框架,而不是由对象自身负责。DI(Dependency Injection,...

    Spring IoC容器实现的结构分析

    Spring IoC容器是Spring框架的核心,它负责管理应用对象的生命周期和依赖关系。通过对IoC(Inversion of Control,控制反转)的实现,Spring容器将对象的创建和组装工作从应用代码中分离出来,使得应用更易于测试和...

    Spring_IOC详解.pdf

    ### Spring_IOC详解:深入探索Spring框架的IOC容器原理 #### 引言 Spring框架作为Java企业级应用开发的基石,其核心组件之一便是IOC(Inverse of Control)容器。IOC容器负责管理应用程序中的对象及其依赖关系,...

    Spring源代码解析(一):IOC容器.doc

    在XmlBeanFactory之上,Spring提供了更抽象的实现,如AbstractBeanFactory和DefaultListableBeanFactory,它们通过模板模式提供了更多的功能,如依赖注入、AOP代理等。 在实际使用中,Spring通常使用...

    浅谈Spring IoC容器的依赖注入原理

    浅谈Spring IoC容器的依赖注入原理 Spring IoC容器的依赖注入原理是Spring框架的核心机制之一,负责将服务对象(Bean)实例化并将其提供给客户端使用。依赖注入原理可以分为两个阶段:IoC容器初始化和Bean实例化。 ...

    spring源码分析(1-10)

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

    Spring源代码自我解析

    IoC(Inversion of Control)即控制反转,是Spring框架的核心特性之一,其本质是通过依赖注入(Dependency Injection, DI)的方式来实现对对象之间依赖关系的管理。在Spring中,BeanFactory是最基础的IoC容器接口,...

    spring源代码中文详解版

    Spring框架的源代码分析主要集中在它的核心特性——控制反转(IOC)容器上。IOC容器是Spring的核心组件,它负责管理应用程序中的对象,也就是所谓的"bean"。BeanFactory接口是IOC容器的基础,它定义了最基础的bean...

    Spring高级之注解驱动开发视频教程

    Spring本身里面包含了两大核心IOC和AOP。IOC负责降低我们代码间的依赖关系,使我们的项目灵活度更高,可复用性更强。AOP是让方法间的各个部分更加独立,达到统一调用执行,使后期维护更加的方便。 SpringMVC本身是...

    Spring Bean创建初始化流程.docx

    在Spring框架中,Bean的创建和初始化是IoC(Inversion of Control)容器的核心功能,这一过程涉及到多个步骤。以下是对Spring Bean创建初始化流程的详细解释: 1. **初始化ApplicationContext**: 开始时,通过`...

    spring 源码分析

    Spring的核心之一是控制反转(Inversion of Control,IoC)模式的应用,而其IoC容器则是整个Spring框架的灵魂所在。通过源码分析Spring,可以帮助开发者深入理解Spring的运作机制,掌握其核心编程思想。 首先,...

    Spring源码分析

    ### Spring源码分析之IOC容器深入探讨 #### 一、Spring框架及IOC容器概述 Spring框架作为企业级Java开发中最常用的轻量级框架之一,以其强大的功能和灵活的设计深受开发者们的喜爱。Spring的核心特性之一便是...

    Spring DI原理.docx

    在Spring框架中,依赖注入通过Spring的Inversion of Control(IoC)容器实现。 当Spring的IoC容器启动并加载Bean定义后,它并不会立即执行依赖注入,而是等到用户首次通过`getBean()`方法请求某个Bean时,或者在...

    1000行代码读懂Spring核心

    - **Spring IoC主线的重要角色**:通过学习,我们可以了解到`BeanDefinition`、`BeanFactory`、`ApplicationContext`等关键组件的工作方式。 - **框架开发思想**:了解如何在代码实现中区分配置与业务逻辑,例如通过...

    spring源码解析

    ### Spring源码解析:IOC容器 #### 一、Spring框架简介 Spring框架是一个开源的轻量级企业级应用开发框架,旨在简化企业级应用的开发过程。它通过一系列的组件和设计模式支持如依赖注入(Dependency Injection, DI...

Global site tag (gtag.js) - Google Analytics