SpringIOC源码分析

SpringIOC源码分析,第1张

SpringIOC源码分析
  • 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()中,

protected  T 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();
        }

    }

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5482280.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-12
下一篇2022-12-12

发表评论

登录后才能评论

评论列表(0条)

    保存