Spring IOC学习总结

BeanFactory

BeanFactory是用于访问Spring Bean容器的根接口,典型的工厂模式,用于生产Bean的一个Bean工厂,其提供了生产Bean所需的最基本规则。
在这里插入图片描述

BeanFactory和FactoryBean区别:

BeanFactory用于生产Bean的一个Bean工厂
FactoryBean类是SpringIOC容器是创建Bean的一种形式,是对Bean的一个扩展点,可以通过implements FactoryBean来使用,它自身是一个Bean,可以使自身这个Bean可以生成其他的Bean,类似于工厂模式,而且这个生成Bean的逻辑可以通过重写getObject()方法由自己来控制。如果需要获取由FactoryBean创建出的Bean对象,通过Bean的名称可以直接获取到,如果需要获取到工厂Bean本身,需要在beanName前面添加&符号,加多少个无所谓,只要以&开头即可。

BeanDefinition

BeanDefinition是bean在spring中的描述(Bean图纸),它是顶级基础接口,用来描述Bean,里面存放Bean元数据,比如Bean类名、scope、属性、构造函数参数列表、依赖的bean、是否是单例类、是否是懒加载等一些列信息。
向上接口:
在这里插入图片描述
BeanMetadataElement接口:BeanDefinition元数据,返回该Bean的来源
AttributeAccessor接口:提供对BeanDefinition属性操作能力
向下接口:
在这里插入图片描述
AbstractBeanDefinition类:抽象类,统一实现了BeanDefinition定义的一部分操作,可以说是定义了BeanDefinition很多默认的属性。 在AbstractBeanDefinition基础上, Spring衍生出了一些列BeaDefinition。

重要接口、类

BeanDefinitionRegistry接口:具有增,查,删BeanDefinition的能力。一次只能注册一个BeanDefinition,一般实现类里都都有一个 private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap()来存储BeanDefinition.
BeanDefinitionReader接口: 既可以使用BeanDefinitionRegistry构造。也可以通过loadBeanDefinitions把配置加载为多个BeanDefinition并注册到BeanDefinitionRegistry中。 是高效版本的BeanDefinitionRegistry,实现类有:
XmlBeanDefinitionReader:从xml中读取BeanDefinition
PropertiesBeanDefinitionReader:从Properties文件读取BeanDefinition
AnnotatedBeanDefinitionReader类:注册了很多后置处理器,并对带有注解的BeanDefinition进行注册。
ClassPathBeanDefinitionScanner类:可以扫描到@Component @Repository @Service @Controller 的BeanDefinition注册到容器中。

方法解释
String: getBeanClassName: 返回当前bean definition定义的类名
ConstructorArgumentValues: getConstructorArgumentValues:返回bean的构造函数参数
String[]: getDependsOn:返回当前bean所依赖的其他bean的名称
String: getFactoryBeanName: 返回factory bean的名称
String: getFactoryMethodName: 返回工厂方法的名称
BeanDefinition: getOriginatingBeanDefinition: 返回原始的BeanDefinition,如果不存在返回null
String: getParentName: 返回当前bean definition的父definition的名字
MutablePropertyValues: getPropertyValues: 返回一个用于新的bean实例上的属性值
String: getScope: 返回当前bean的目标范围
boolean: isAbstract: 当前bean是否是abstract,意味着不能被实例化
boolean: isLazyInit: bean是否是延迟初始化
boolean: isPrimary: bean是否为自动装配的主要候选bean
boolean: isPrototype: bean是否是多实例
boolean: isSingleton: bean是否是单例
void: setAutowiredCandidate(boolean): 设置bean是否对其他bean是自动装配的候选bean
void: setBeanClassName(String): 指定bean definition的类名
void: setDependsOn(String ...): 设置当前bean初始化所依赖的beans的名称
void: setFactoryBeanName(String): 如果factory bean的名称
void: setFactoryMethodName(String): 设置工厂的方法名
void: setLazyInit(boolean lazyInit): 设置是否延迟初始化
void: setParentName(String): 设置父definition的名称
void: setPrimary(boolean): 设置是否主要的候选bean
void: setScope(String): 设置bean的范围,如:单例,多实例
AnnotationConfigApplicationContext结构关系在这里插入图片描述

Spring IOC容器的加载过程

//创建AnnotationConfigApplicationContext对象
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);

//根据参数类型可以知道,可以传入多个annotatedClasses
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		//初始化BeanFactory,Bean读取器,Bean扫描器
		this();
		//注册配置类到BeanDefinitionMap中
		register(annotatedClasses);
		//刷新IOC容器(核心方法)
		refresh();
}   
this()方法中有三步操作:

1、调用本类无参构造函数,会先调用父类GenericApplicationContext的构造函数,初始化DefaultListableBeanFactory,并且赋值给BeanFactory

2、本类的构造函数里面,初始化了一个读取器:AnnotatedBeanDefinitionReader reader,Reader中注册了很多后置处理器,比如ConfigurationClassPostProcessor,在这个类中,会读取到加了@Configuration的配置类(加了这个注解的话,会为配置类创建cglib动态代理,保证每次都去单例池里拿,而不是重复加载),还会读到@ComponentScan、@ComponentScans注解扫描的包,以及@Import@Bean等注解,是用来解析配置类的处理器。还有AutowiredAnnotationBeanPostProcessor,用于读取@Autowired注入的类。还注册了很多其他用于解析注解的Bean定义。后续通过调用invokeBeanFactoryPostProcessors解析注册过的配置

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		//把ApplicationContext对象赋值给AnnotatedBeanDefinitionReader
		this.registry = registry;
		//用户处理条件注解 @Conditional os.name
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
		//注册一些内置的后置处理器
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}

3、还有一个扫描器ClassPathBeanDefinitionScanner scanner,此处scanner实例不作为配置类中的扫描实例,此实例是给单独提供给ApplicationContext去扫描包的,不参与配置类的扫描(解析配置类时会new一个scanner对象进行扫描),我们可以传入构造参数时为空,不指定配置类,然后调用scan方法手动去扫描包。

refresh()方法:

IOC加载过程中最主要的是invokeBeanFactoryPostProcessors、finishBeanFactoryInitialization
两个方法

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			//准备刷新上下文环境
			prepareRefresh();
			//获取告诉子类初始化Bean工厂  不同工厂不同实现
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
			//对bean工厂进行填充属性
			prepareBeanFactory(beanFactory);
			try {
				//留个子类去实现该接口
				postProcessBeanFactory(beanFactory);
				//将class扫描成beanDefinition,调用Bean工厂的后置处理器,解析注册过的配置类,注册Bean定义
				invokeBeanFactoryPostProcessors(beanFactory);
				//注册Bean的后置处理器 
				registerBeanPostProcessors(beanFactory);
				//初始化国际化资源处理器.
				initMessageSource();
				//创建事件多播器
				initApplicationEventMulticaster();
				//这个方法同样也是留个子类实现的springboot也是从这个方法进行启动tomcat的.
				onRefresh();
				//把事件监听器注册到多播器上
				registerListeners();
				//实例化单例Bean.
				finishBeanFactoryInitialization(beanFactory);
				//最后容器刷新 发布刷新事件(Spring cloud也是从这里启动的)
				finishRefresh();
			}
			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception  encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}
				destroyBeans();
				cancelRefresh(ex);
				throw ex;
			}
			finally {
				resetCommonCaches();
			}
		}
	}
finishBeanFactoryInitialization方法:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// 为我们的bean工厂创建类型转化器  Convert
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		//处理Aspect
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}
		beanFactory.setTempClassLoader(null);
		//冻结所有的bean定义,注册的bean定义将不被修改或任何进一步的处理
		beanFactory.freezeConfiguration();
		//实例化剩余的单实例bean
		beanFactory.preInstantiateSingletons();
	}

preInstantiateSingletons方法:
public void preInstantiateSingletons() throws BeansException {
		if (logger.isDebugEnabled()) {
			logger.debug("Pre-instantiating singletons in " + this);
		}
		//获取容器中所有Bean定义的名称(包括通过ComponentScan扫描到的、@Bean注入的等)
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
		//循环所有的Bean定义名称
		for (String beanName : beanNames) {
			//合并不同类型的Bean定义,转换为统一的RootBeanDefinition类型,方便后续处理
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//根据Bean定义判断:不是抽象的 && 是单例的 && 不是懒加载的
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				//判断是不是FactoryBean(是否实现了FactoryBean接口)
				if (isFactoryBean(beanName)) {
					// 是工厂Bean会先生成实际的Beab,beanName是用来获取实Bean的
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						final FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
											((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						//getBean(工厂Bean)
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {//非工厂Bean
					getBean(beanName);
				}
			}
		}
		//到这里所有的单实例的Bean已经记录到单实例Bean到缓存池中
		for (String beanName : beanNames) {
			//从单例缓存池中获取所有的对象
			Object singletonInstance = getSingleton(beanName);
			//判断当前的Bean是否实现了SmartInitializingSingleton接口
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					//触发实例化之后的方法afterSingletonsInstantiated
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}
doGetBean方法:
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
		//传入进来的name可能是别名, 也有可能是工厂bean的name,转换成真实的name
		final String beanName = transformedBeanName(name);
		Object bean;
		//尝试去缓存中获取对象
		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 + "'");
				}
			}
			 //如果 sharedInstance 是普通的单例 bean,下面的方法会直接返回。
			 //如果是 FactoryBean 类型的,则需调用 getObject 工厂方法获取真正的bean 实例。
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		else {
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			//判断AbstractBeanFacotry工厂是否有父工厂,一般情况下,只有Spring 和SpringMvc整合的时才会有父子容器的概念
			//比如我们的Controller中注入Service的时候,发现我们依赖的是一个引用对象,那么他就会调用getBean去把service找出来
			//当前所在的容器如果是web子容器,那么就会先去父容器找
			BeanFactory parentBeanFactory = getParentBeanFactory();
			//若存在父工厂,并且当前的bean工厂不存在当前的bean定义,那么bean定义就存在于父beanFacotry中
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				//获取bean的原始名称
				String nameToLookup = originalBeanName(name);
				//如果为 AbstractBeanFactory 类型,委托父类处理
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					//委托给构造函数 getBean() 处理
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else {
					//委托给普通的 getBean() 处理
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}
			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			try {
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				//检查当前创建的bean定义是不是抽象的bean定义
				checkMergedBeanDefinition(mbd, beanName, args);
				//依赖bean的名称
				String[] dependsOn = mbd.getDependsOn();
					//判断是不是dependsOn的bean
					//@dependsOn可以指定某个bean再另一个bean之前完成实例化
					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 {
							//获取depentceOn的bean
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}
				//创建单例bean
				if (mbd.isSingleton()) {
					//把beanName 和一个singletonFactory 并且传入一个回调对象用于回调
					//添加bean到singletonsCurrentlyInCreation中,标记为正在创建
					sharedInstance = getSingleton(beanName, () -> {
						try {
							//进入创建bean的逻辑
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							//创建bean的过程中发生异常,需要销毁关于当前bean的所有信息
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				//创建多例bean
				else if (mbd.isPrototype()) {
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}
				//省略后续代码......
		return (T) bean;
	}
createBean方法:
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;
		// 确保此时的bean已经被解析了
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}
		try {
			//验证和准备覆盖方法( 仅在XML方式中)
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}
		try {
			//第1个bean后置处理器
			//通过bean的后置处理器来进行后置处理生成代理对象
			//这里不会生成代理对象,只会解析的aop切面信息进行缓存
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				//返回后置处理器处理后的bean
				return bean; 
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}
		try {
			//真正创建bean实例对象的过程
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isDebugEnabled()) {
				logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}
doCreateBean方法:

对bean进行实例化(createBeanInstance)、填充属性(populateBean)、初始化(initializeBean)

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			//从没有完成的FactoryBean中移除
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//创建bean的实例化对象
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		//从beanWrapper中获取我们的早期对象
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					//进行后置处理 @AutoWired @Value的注解的预解析
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}
		//缓存单例到三级缓存中,防止循环依赖
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
 		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			//把早期对象包装成一个singletonFactory对象
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}
		Object exposedObject = bean;
		try {
			//对属性进行赋值(@Autowired、@Value)
			populateBean(beanName, mbd, instanceWrapper);
			//进行对象初始化操作(调用后置处理器,执行AOP所以可能生成代理对象)
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}
		//省略部分代码......
		try {
			//注册销毁的bean的销毁接口
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}
		return exposedObject;
	}
IOC加载过程总结:

首先通过new AnnotationConfigApplicationContext构造一个ApplicationContext
1、这个构造方法中会实例化BeanDefinitionReader,Reader中注册了很多后置处理器,比如ConfigurationClassPostProcessor类,在这个类中,会读取到加了@Configuration的配置类,还会读到@ComponentScan、@ComponentScans注解扫描的包,以及@Import@Bean等注解。还有AutowiredAnnotationBeanPostProcessor等,用于读取@Autowired注入的类。以及很多其他核心类。
2、还有一个扫描器BeanDefinitionScanner ,这个scanner实例是给单独提供给applicationContext去扫描包的,可以通过这个scanner手动扫描包。
3、再通过BeanDefinitionRegistry注册配置类,此时配置类还没有解析成Bean定义,只是把解析需要的一些类进行了初始化。
4、在refresh()方法中,invokeBeanFactoryPostProcessors方法会把class扫描成beanDefinition,调用Bean工厂的后置处理器,解析注册过的配置类,注册Bean定义到BeanDefinitionMap中
5、然后在finishBeanFactoryInitialization方法中,会调用preInstantiateSingletons方法,这个方法中会判断是否符合生产标准(不是抽象的 && 是单例的 && 不是懒加载的),再判断是否是FactoryBean,区分工厂bean和非工厂bean来分别调用getBean()方法;
6、getBean会调用doGetBean方法,在doGetBean中会先从一级缓存中拿,拿到了就返回,拿不到就调用createBean方法,
7、createBean会第一次调用Bean的后置处理器,通过后置处理器可以阻止Bean的创建,这里可以解析Aop切面信息进行缓存
8、最后调用doCreateBean方法,真正的创建Bean的实例对象,在进行实例化(createBeanInstance)、填充属性(populateBean)、初始化(initializeBean)后最终把Bean放入一级缓存

Bean的生命周期:

总体可以分为六个阶段Bean定义、实例化、属性赋值、初始化、生存期、销毁
Bean定义:BeanFactoryPostProcessors会解析BeanDefinitionReader注册过的配置类,并且注册解析完成的Bean定义到BeanDefinitionMap中。
实例化:这个时候Bean的对象是最原始的,基本的属性还没有设置。
属性赋值:然后填充属性,做完这一步,Bean象基本是完整的了,@Autowired@Value注解已经解析完毕,依赖注入完成。
初始化:检查Bean实现的Awareness接口,根据不同实现接口调用不同的初始化方法,然后还会检查三种初始化回调方法,执行顺序为:

1、@PostConstruct注解标记的初始化方法
2、实现InitializingBean接口,重写了afterPropertiesSet的方法
3、xml中,bean标签里配置init-mothod属性,class中指定的方法。

生存期:这时候的Bean已经被准备就绪了,会一直停留在应用的上下文中,直到被销毁;
销毁:单例Bean的应用的上下文被销毁,在销毁之前会检查并调用:

1、@PreDestroy注释标注的回调方法
2、Bean实现了DisposableBean接口的话,调用destroy()方法
3、还有XML中,Bean定义包含destroy-method或@Bean(destroyMethod="…")指定的方法
什么是Spring应用上下文:

是对Spring容器的一种抽象化描述,Spring的核心是容器,容器并不唯一,大概分为两类:
一种是BeanFactory,是最简单的容器,只能提供基本的DI功能
还有一种就是继承了BeanFactory派生出来的应用上下文,ApplicationContext这些应用上下文的高级接口。对于上下文抽象接口,Spring也提供了多种类型的容器实现:

1、AnnotationConfigApplicationContext:从一个或多个基于java的配置类中加载上下文定义,适用于java注解的方式;

2、ClassPathXmlApplicationContext:从类路径下的一个或多个xml配置文件中加载上下文定义,适用于xml配置的方式;

3、FileSystemXmlApplicationContext:从文件系统下的一个或多个xml配置文件中加载上下文定义,也就是说系统盘符中加载xml配置文件;

4、AnnotationConfigWebApplicationContext:专门为web应用准备的,适用于注解方式;

5、XmlWebApplicationContext:从web应用下的一个或多个xml配置文件加载上下文定义,适用于xml配置方式。
BeanFactoryPostProcessors后置处理器执行流程:

1、new AnnotationConfigApplicationContext 时,会在AnnotatedBeanDefinitionReader中注册一个ConfigurationClassPostProcessor,这个是用来解析配置类的Bean工厂后置处理器。

2、在register()方法中把配置类注册到BeanDefinitionMap中。

3、在refresh()方法中的invokeBeanFactoryPostProcessors()方法中会调用所有类型是BeanDefinitionRegistryPostProcessor的bean定义,也就是拿到了ConfigurationClassPostProcessor的bean定义(此时BeanDefinitionMap中的bean定义只有ConfigurationClassPostProcessor是Registry类型的),调用getBean进行实例化。

4、然后调用ConfigurationClassPostProcessor中的processConfigBeanDefinitions方法,在这里会判断是否是完全配置类是不完全配置类(所有的带有@Configuration、@Bean、@Component、@import等注解的都会被认为是配置类,带有@Configuration的会是完全配置类,会为其创建cglib动态代理,防止bean重复加载),然后拿到所有配置类,因为现在BeanDefinitionMap中只有完全配置类,所以会拿到所有的完全配置类。

5、然后会new一个ConfigurationClassParser配置类解析器,通过parse()方法进行解析,首先会判断是否是通过@import导入进来的配置类,然后调用doProcessConfigurationClass()进行真正的配置类解析。

6、在doProcessConfigurationClass()中会先处理@propertySource注解(指定XML配置),然后拿到@ComponentScan 的所有属性,对属性中配置的包进行循环扫描,循环中会判断是不是@ComponentScan的配置中需要过滤或包含,并且不是接口的bean(Mybatis重写了判断接口的方法,所以xml才可以被扫描到)。

7、最后调用doScan,把包路径转换为物理资源路径(. -> /),并且拿到路径下所有的.class文件,把这些bean解析成Bean定义,通过BeanDefinitionRegistry注册到BeanDefinitionMap中(通过scanner扫描到的重复的beanName会报错,但是通过@bean注入的重复的bean会覆盖)。

循环依赖问题:

现有两个对象A、B,A为AOP对象,A依赖B,B依赖A,A先开始创建。

1、首先读取BeanDefinition,先读到了A、所以先调用A的getBean()方法,会先从一级缓存中尝试拿对象,如果拿到了就直接返回,但此时一级缓存是没有的,并且A也不是正在创建的状态。然后会把A放到一个set里,这个set就是标记A对象是一个正在创建的对象,并且实例化A,然后创建一个A的函数接口存储到三级缓存中。

2、然后解析A,对A进行属性赋值,就会读到@Autowired注入的B,此时就会递归去调用getBean(),开始创建B,同样也是先从一集缓存中拿B,没拿到,并且B也不是正在创建的状态。然后把B也放进set,标记成正在创建,并且实例化B,然后创建一个B的函数接口存储到三级缓存中,此时A、B都是正在创建的状态。

3、然后解析B,就读到了@Autowired注入的A,再递归调用getBean去拿A,还是会先从一级缓存拿,仍然没拿到,但此时A是正在创建状态,就表示是在循环依赖,就会去二级缓存拿,二级缓存也没有,再从三级缓存拿,三级缓存会先调用之前存储的A的函数接口,判断A是否要创建AOP对象,如果需要就创建AOP对象返回,没有就返回原实例对象,A是,所以会创建并且把代理后的A放到二级缓存中(此时放到二级缓存中也可以解决复杂循环依赖下重复创建AOP对象的问题,比如A依赖B,B依赖A,C也依赖A,A被依赖两次,放到二级缓存中就不会创建两次AOP对象了)。

4、此时B就拿到了A的实例化对象,然后通过反射,把B中的A完成属性赋值,然后完成B的初始化,把B放到一级缓存里。

5、B创建完后返回给A,因为此时A是一个新的AOP对象,所以还要去二级缓存中拿到代理对象赋给当前的A实例,然后完成初始化,最后把二级缓存中的BeanA放入到一级缓存,并且删除二级和三级缓存中的beanA,Bean创建完成。

总结:

其实在单线程下,一级缓存就能解决循环依赖问题,但是多线程下就可能会导致另一个需要依赖A的Bean拿到不完成整的bean。

所以就用二级缓存+锁来解决,把整个创建过程和从二三级缓存获取bean的时候加两把锁,例如T1创建A时,会先从一级缓存获取,然后在获取二级缓存的时候加锁,此时如果T2线程进来拿A的实例就会先获取一级缓存,没有获取到就阻塞在获取二级缓存之前。A创建完成之后会删除二三级缓存中的实例,所以此时只有一级缓存中有A对象。T2此时获取到锁,但是拿不到A,就会继续走创建流程,但在创建之前会再次从一级缓存中获取A对象,因为此时A已经在一级缓存中了,所以获取成功,通过这种双重校验机制,保证了Bean不会重复创建。

而三级缓存是为了确保只在循环依赖情况下,提前创建AOP对象。因为普通对象会在初始化后通过Bean的后置处理器创建AOP对象,如果A对象是一个需要AOP的对象,如果是初始化后再创建代理对象,在B注入A时,A就不是一个代理对象了,所以需要提前创建。三级缓存中不存储bean的实例,而是存储每个Bean绑定的函数接口,通过这个接口去创建该BeanAOP对象。其实如果在实例化之后就创建AOP对象然后把AOP对象放到二级缓存中,只使用二级缓存就能解决循环依赖下AOP的问题。三级缓存其实就是为了保证代码的单一职责性,用来解偶才衍生出来的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值