
- bean的生命周期
- 循环依赖
- 三级缓存
- factorybena和benafactoey
- appliaationcontext和beanfactory的区别
- ioc容器
bean——数据结构——map——三级缓存
IOC容器
context.getBean()——什么时候调用
容器中如何创建bean——工厂,反射——配置文件(xml)
Spring介绍Spring是一个控制反转的框架,IOC是通过依赖注入来实现的;其他的依赖反转的实现方式是JNDI,Spring中有两个主要的容器系列——BeanFactory和ApplicationContext,其中BeanFactory只实现了容器的基本功能(比如),同时规定了Bean容器最基本的额功能规范,而ApplicationContext是容器的高级形态,增加了许多面向框架的特性,比如——...
Spring通过BeanDefinition来管理基于bean及他们之间的依赖关系,抽象bean的定义,
Benafanctory和ApplicationContext之间的区别——BeanFactory只提供Ioc容器最基本的特性和功能,ApplicationContext在扩展BeanFactory的基础上增加了许多高级特性,必须消息,国际化,事件发布等
SpringIoc容器的设计接口图:
分析——
ConfigurableBeanFactory的这条设计路线是BeanFactory设计路线,定义了基本的IoC容器规范,比如getBean()这样的基本方法;DefautlListableBeanFactory就是实现了ConfigurableBeanFactory;
而ApplicationContext细化了BeanFactory的功能,并且扩展了一些高级特性;
具体的实现类有——DefaultListableBeanFactory,XMLBeanFactory,ApplicationContext;
使用&获取FactoryBean本身,比如MyOnlyObject是一个FactoryBean,使用&MyOnlyObject得到的是FactoryBean本身,而不是由这个FactoryBean产生的Bean对象;
BeanFactory设计详解getBean()——获取Bean,通过指定名字来索引的(实际的bean是存储在map当中的;);同时定义了各种带参数的getBean()方法,来进行类型匹配等;
containsBean()——是否包含
isSingleton()——
isPrototype()——
isTypeMatch()——
getType()——
getAliases()——获取别名
XMLBeanFactroy分析XMLBeanfactory类图——XMLBeanfactory继承了DefaultListableBeanFactory,最上层是对ConfigurableBeanFactory接口的实现;
在Spring中,把DefaultListableBeanFactory作为一个默认的功能完整的BeanFactory的实现来使用的;
XMLBeanFactory对bean的配置信息的读取是通过XmlBeanDefinitionReader来完成的,同时,配置信息的XML文件是通过Resource对象来抽象的;——解耦设计
然后将Resource对象作为构造参数传给BeanFactory的构造器;
IOC容器的初始化过程简单来说,IOC容器的初始化是有refresh()方法来完成的;这个过程包括——Recourse的定位,载入和注册三个基本过程;
Spring将这三个基本过程分开,使用不同的模块来完成;ResourceLoader,BeanDefinitionReader;
第一个过程是Resource定位——由ResourceLoader通过统一的Resource接口来完成,
第二个过程是BeanDefinition的载入——
第三个过程是向IOC容器注册定义好的bean——通过BeanDefinitionRegistry接口的实现来完成的,将BeanDefinition注入到一个hashMap中;
容器的初始化不会包含依赖注入过程;依赖注入发生在第一次使用getBean()向容器获取bean的时候;但如果在Bean定义信息中设置了lazyinit属性,则在初始化的时候就会完成依赖注入;
IOC容器的依赖注入依赖注入的过程发生在getBean()方法,具体是调用doGetBean()方法,在doGetBean()中,
protectedT doGetBean( String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { String beanName = transformedBeanName(name); Object beanInstance; // 先从缓存中获取bean,获取那些事情已经被创建过的单例bean,对这种bean的请求不需要重复创建 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } //这里完成的是FactoryBean的相关处理, beanInstance = 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); } // 这里对IOC容器中的BeanDefinition是否存在进行检查,检查当前容器中是否能获取到需要的Bean,如果获取不到,则在父工厂中检查,一直顺着双亲链向上查找 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } //这里根据beanName获取BeanDefinition StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate") .tag("beanName", name); try { if (requiredType != null) { beanCreation.tag("beanType", requiredType::toString); } RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); //获取当前bean的所有依赖bean,会触发getBean()的递归调用;直到取到一个没有任何依赖的bean为止; String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); try { //getBean()的递归调用 getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // 这里通过调用createBean()方法创建单例模式的bean;这里有一个回调函数getObject()会在getSingleton中调用ObjectFactory()的createBean(); if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { 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; } }); beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //这里创建prototype bean的地方; 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); } beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); if (!StringUtils.hasLength(scopeName)) { throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'"); } 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); } }); beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new ScopeNotActiveException(beanName, scopeName, ex); } } } catch (BeansException ex) { beanCreation.tag("exception", ex.getClass().toString()); beanCreation.tag("message", String.valueOf(ex.getMessage())); cleanupAfterBeanCreationFailure(beanName); throw ex; } finally { beanCreation.end(); } } return adaptBeanInstance(name, beanInstance, requiredType); }
对于IOC容器的使用,Spring提供了许多的参数配置,每一个参数配置实际上代表了一个IOC容器的实现特性,这些特性的实现很多都要在对Bean生命周期进行管理的过程中完成,尽管可以用最简单的方式来描述IOC容器,将它视为一个hashMap,但只能说这个hashMap是容器的最基本的数据结构,而不是IOC容器的全部;SPring IOC容器的作为一个框架,其价值体现在一系列相关的框架特性上,这些特性以依赖反转的模式实现为核心;
依赖注入过程的详解——getBean是依赖注入的起点;之后会调用createBean,在这个过程中,bean会根据BeanDefinition定义的要求生成;createBean()生成bean的同时对bean初始化进行了处理;比如定义了bean的后置处理器(AOP在这个过程中实现)
Spring如何加载配置文件到应用中的——new classpathxmlapplocationContext(”beans.xml“)——不同的配置文件——定义读取配置文件的规范接口———yml、propetties,json,xml——bean的定义信息
读取定义信息——BeanDefinitionReader——定义文件读取——接口,对应不同的实现;
解析——
实例化bean——实例化和初始化的区别——(python中的_new_()和_inti_()
容器benafactory中的refresh()方法——
prepareRefresh()
createBeanFactory()——new defaultListableBeanFactory()
反射中获取Class对象的三种方法——Class.forname()对象.getClass()类.Class()
PostOrocessor——后置处理器——扩展功能——beanfactorypostprcessor
AOP——在BeanPostProcessor的bbefore和after方法中实现;
SpringIOC容器的初始化过程——————————————————————————
new ClassPathXmlApplicationContext()——
super
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
super(parent);
this.setConfigLocations(configLocations);
if (refresh) {
this.refresh();
}
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)