您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 咨询培训 > Spring源码分析之IoC容器篇
Spring源码分析之IoC容器篇作者:imaginecup做最棒的软件开发交流社区第1/62页本书由JavaEye提供的电子书DIY功能自动生成于2010-10-02目录1.Spring1.1Spring源码解析1IOC容器的初始化....................................................31.2Spring源码解析2IOC容器的初始化..................................................131.3Spring源码解析3IOC容器的初始化...................................................301.4Spring源码解析依赖注入...........................................................331.5Spring源码解析lazy-init属性和预实例化..............................................561.6Spring源码解析BeanPostProcessor的实现............................................58页1.1Spring源码解析1IOC容器的初始化发表时间:2010-10-01参考《Spring技术内幕》一书:IoC容器的基本接口是由BeanFactory来定义的,也就是说BeanFactory定义了IoC容器的最基本的形式,并且提供了IoC容器所应该遵守的最基本的服务契约。BeanFactory只是一个接口类,并没有给出容器的具体实现。DefaultListableBeanFactory,XmlBeanFactory,ApplicationContext,FileSystemXmlBeanFactory,ClassPathXmlBeanFactory都实现了BeanFactory接口并且扩展了IoC容器的功能。首先介绍BeanFactory:publicinterfaceBeanFactory{//这里是对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,//如果需要得到工厂本身,需要转义StringFACTORY_BEAN_PREFIX=&;//这里根据bean的名字,在IOC容器中得到bean实例,这个IOC容器就是一个大的抽象工厂。ObjectgetBean(Stringname)throwsBeansException;//这里根据bean的名字和Class类型来得到bean实例,和上面的方法不同在于它会抛出异常:如果根据名字取得的bean实例的Class类型和需要的不同的话。ObjectgetBean(Stringname,ClassrequiredType)throwsBeansException;//这里提供对bean的检索,看看是否在IOC容器有这个名字的beanbooleancontainsBean(Stringname);//这里根据bean名字得到bean实例,并同时判断这个bean是不是单件booleanisSingleton(Stringname)throwsNoSuchBeanDefinitionException;//这里对得到bean实例的Class类型ClassgetType(Stringname)throwsNoSuchBeanDefinitionException;//这里得到bean的别名,如果根据别名检索,那么其原名也会被检索出来页String[]getAliases(Stringname);}用户使用容器时,可以使用转义字符'&'来得到FactoryBean本身,用来区分通过容器来获取FactoryBean产生的对象还是获取FactoryBean本身。在Spring中所有的Bean都是由BeanFactory来管理的,而对于FactoryBean,它是一个能产生或者修饰对象生成的工厂Bean。BeanFactory和FactoryBean:BeanFactory它指的是IoC容器的编程抽象,而FactoryBean指的是一个抽象工厂,对它的调用返回的是工厂产生的对象,而不是它本身。我们先通过编程实现IoC容器:publicclassUserBeanFatory{publicstaticvoidmain(String[]args){//创建一个BeanFactory,这里使用DefaultListableBeanFactory,包含IoC容器的重要功能DefaultListableBeanFactoryfactory=newDefaultListableBeanFactory();/**创建一个载入BeanDefinition的读取器,这里使用XmlBeanDefinitionReader来载入XML文件形式的*BeanDefinition,使用一个回调配置给BeanFactory*/XmlBeanDefinitionReaderreader=newXmlBeanDefinitionReader(factory);/**创建Ioc配置文件的抽象资源,这个抽象资源中包含了BeanDefinition的定义信息*/ClassPathResourceres=newClassPathResource(applicationContext-beans.xml);/**从定义好的资源位置读入配置信息,具体的解析过程是由XmlBeanDefinitionReader*来完成的。完成整个的载入与注册Bean定义之后,需要的IoC容器就建立起来了页*/reader.loadBeanDefinitions(res);Useruser=(User)factory.getBean(user);System.out.println(user.getUsername()+:+user.getPassword());//等价于XmlBeanFactoryxmlfactory=newXmlBeanFactory(newClassPathResource(applicationContext-beans.xml));Userxmluser=(User)factory.getBean(user);System.out.println(xmluser.getUsername()+:+xmluser.getPassword());ApplicationContextac=newFileSystemXmlApplicationContext(D:/java/kcsj/SourceXmpBeanFactory/src/applicationContext-beans.xml);ac.getBean(user);}}由上面我们可以想到IoC容器初始化分为三个步骤:1BeanDefinition的Resource定位2BeanDefinition的载入和解析3BeanDefinition的注册我们先看BeanDefinition的Resource定位:下面以FileSystemXmlApplicationContext为例,通过分析这个ApplicationContext的实现来看看它是怎样完成Resource的定位的。ApplicationContextac=newFileSystemXmlApplicationContext(D:/java/kcsj/SourceXmpBeanFactory/src/applicationContext-beans.xml);我们首先看看FileSystemXmlApplicationContext的源码:页publicclassFileSystemXmlApplicationContextextendsAbstractXmlApplicationContext{.....publicFileSystemXmlApplicationContext(String[]configLocations,booleanrefresh,ApplicationContextparent)throwsBeansException{super(parent);setConfigLocations(configLocations);if(refresh){refresh();}}}在FileSystemXmlApplicationContext的构造函数中完成了两部分功能:1是设置BeanDefinition的配置文件的路径,是的所有在配置文件中的BeanDefinition都能得到有效地处理;2就是通过refresh()方法启动了IoC容器的初始化。AbstractApplicationContext的refresh()方法源码解析:publicvoidrefresh()throwsBeansException,IllegalStateException{synchronized(this.startupShutdownMonitor){//Preparethiscontextforrefreshing.prepareRefresh();//Tellthesubclasstorefreshtheinternalbeanfactory.ConfigurableListableBeanFactorybeanFactory=obtainFreshBeanFactory();//Preparethebeanfactoryforuseinthiscontext.prepareBeanFactory(beanFactory);try{//Allowspost-processingofthebeanfactoryincontextsubclasses.postProcessBeanFactory(beanFactory);//Invokefactoryprocessorsregisteredasbeansinthecontext.页invokeBeanFactoryPostProcessors(beanFactory);//Registerbeanprocessorsthatinterceptbeancreation.registerBeanPostProcessors(beanFactory);//Initializemessagesourceforthiscontext.initMessageSource();//Initializeeventmulticasterforthiscontext.initApplicationEventMulticaster();//Initializeotherspecialbeansinspecificcontextsubclasses.onRefresh();//Checkforlistenerbeansandregisterthem.registerListeners();//Instantiateallremaining(non-lazy-init)singletons.fi
本文标题:Spring源码分析之IoC容器篇
链接地址:https://www.777doc.com/doc-6224878 .html