Spring 源码系列——IOC及DI

灌水

spring 用了很长时间了,譬如 IOC、DI、AOP之类高端大气上档次的专业名词是如雷贯耳,真是可远观而不可亵玩。
如今工作一年了,是时候解开她神秘的面纱,开始攻城略地!

先写段入口代码


	/**
	* ApplicationContext的作用 :
	* 	1.用于访问应用程序组件的Bean工厂方法
	*   2.以通用方式加载文件资源的能力。
	* 	3.能够向注册的监听器发布事件。
	* 	4.解决消息的能力,支持国际化。
	*/
	@Test
	public void test() {
		//通过ClassPathXmlApplicationContext加载我们配置的xml文件
		ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
		User bean = (User) context.getBean("a", User.class);
		System.out.println(bean.toString());
	}

运行程序,进入ClassPathXmlApplicationContext

	/**
	*	String [] configLocations 这里面是我们要加载的xml文件
	*	boolean refresh 是否自动刷新上下文,加载所有bean定义并创建所有单例。
	*	或者,在进一步配置上下文之后手动调用refresh。
	*/
	public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
   		throws BeansException {

   	super(parent);
   	// 这一步是将我们的配置文件加载进ApplicationContext 中。
   	setConfigLocations(configLocations);
   	if (refresh) {
   		//关键部位:更新操作
   		refresh();
   	}
   }

进入refresh()方法

开始碰触IOC核心。
  • ClassPathXmlApplicationContext 调用父类的refresh();
   	@Override
	public void refresh() throws BeansException, IllegalStateException {
			//进入程序先获取对象锁,防止在并发情况下出现异常。
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			//在更新上下文前先做一些准备
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			// 这里面就是 获取 IOC bean 工厂。 下面重点看这块。
			//  ----> 根据断点追总结果,将解析的xml文件得到的Bean定义对象保存到MAP 中
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			// 设置容器标准特征,添加了一些后置处理器
			// 将beanPostProcessor注册监听;
			prepareBeanFactory(beanFactory);

			try {
				//待续-------------------------------------------------------------
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				// 将 BeanPOstProcessor注册给BeanFactory
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				// 国际化配置
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				//注册监听器 
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				//做了三件事情
				//1. Bean 的实例化
				//2. 属性注入
				//3.执行后置处理器的一些初始化方法
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

解读prepareRefresh()

/**
	 * Prepare this context for refreshing, setting its startup date and
	 * active flag as well as performing any initialization of property sources.
	 */
	protected void prepareRefresh() {
	
	 	//设置上下文启动时间
		this.startupDate = System.currentTimeMillis();
		//下面两个set是context设置存活标志。
		this.closed.set(false);
		this.active.set(true);
		//打印日志,不用管
		if (logger.isInfoEnabled()) {
			logger.info("Refreshing " + this);
		}

		// Initialize any placeholder property sources in the context environment
		//这里是处理xml文件中的占位符初始化。比如我们数据库中一些参数配置在properties文件中,在系统加载时会将参数值填充进去。
		initPropertySources();

		// Validate that all properties marked as required are resolvable
		// see ConfigurablePropertyResolver#setRequiredProperties
		//检查运行环境
		getEnvironment().validateRequiredProperties();

		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
	}

解读 obtainFreshBeanFactory();

流程:

  1. 获取bean容器
  2. 设置是否可以重写Bean
  3. 设置是否可以循环依赖
  4. 创建Xml Bean定义的解析器设置到beanFactory
  5. 解析xml,放入beanDefintionMap
  6. 设置序列号
/**
*/
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	// 这个方法主要获取这个更新context 潜在的bean工厂,如果之前存在就销毁beans实例、关闭bean工厂,{  destroyBeans(); closeBeanFactory();} & 在下面继续贴这个方法的解析!
		refreshBeanFactory();
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}
分析 refreshBeanFactory()
protected final void refreshBeanFactory() throws BeansException {
		//如果存在beanfactory 执行销毁
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			// 这里获取默认的bean 容器! 这个就是我们要寻找的IOC容器...是孕育我们整个项目Bean的伊甸园!
			// return new DefaultListableBeanFactory(getInternalParentBeanFactory());
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			//给beanfactory设置序列化ID,后面有需要的话可以通过序列化ID,实例一个beanFactory
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);
			//Loads the bean definitions via an XmlBeanDefinitionReader.
			//通过XmlBeanDefinitionReader 加载 bean 定义。(BeanDefinition:相当于人 的一个身份证)
			//initBeanDefinitionReader(beanDefinitionReader); 这个东西初始化beanDefinition阅读器
			//loadBeanDefinitions(beanDefinitionReader);使用给定的XmlBeanDefinitionReader加载bean定义
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
		
			--------------------------------
	}
分析 loadBeanDefinitions(beanFactory);
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
		
			--------------------------------
		if (!currentResources.add(encodedResource)) {
			throw new BeanDefinitionStoreException(
					"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
		}
		try {
			InputStream inputStream = encodedResource.getResource().getInputStream();
			try {
				InputSource inputSource = new InputSource(inputStream);
				if (encodedResource.getEncoding() != null) {
					inputSource.setEncoding(encodedResource.getEncoding());
				}
				//由此加载beanDefinitions
				return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
			}
			--------------------------------


	=============   进入doLoadBeanDefinitions  =============

	protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {
		try {
			//加载xml配置文件的DOM树
			Document doc = doLoadDocument(inputSource, resource);
			return registerBeanDefinitions(doc, resource);
		}
			--------------------------------

=============   进入registerBeanDefinitions  =============

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		// 获取注册之前的beanDefinitions;
		int countBefore = getRegistry().getBeanDefinitionCount();
		// 注册beanDefinnitions 
			
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		            |
		            |
		            V
			// preProcessXml(root);  前处理器  这个东西啥也没有干。 
			// parseBeanDefinitions(root, this.delegate);  // bean文件解析的主要部分。
			 		|
		            |
		            V
			//   parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {\
			--------------------------------
						if (node instanceof Element) {
					Element ele = (Element) node;
					if (delegate.isDefaultNamespace(ele)) {
						//处理默认的节点标签(import、alias、bean)
						parseDefaultElement(ele, delegate);
								|
					            |
					            V
					     // protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
					     //bean 对象定义
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				// Register the final decorated instance.
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
								|
					            |
					            V
		  registerBeanDefinition(String beanName, BeanDefinition beanDefinition){
					// Still in startup registration phase
					//到这里beanFactory就彻底创建完毕
					//beanDefinitionMap 存放了所有的eanDefinition
				this.beanDefinitionMap.put(beanName, beanDefinition);
					// 存放每一个注册的Bean名称
				this.beanDefinitionNames.add(beanName);
				this.manualSingletonNames.remove(beanName);
}
			}

//
					}
					else {
					// 处理有命名空间的Bean 
						delegate.parseCustomElement(ele);
					}
				}
			--------------------------------
				}
			// postProcessXml(root); 后处理器 
		// 再一次获取已经注册的bean数量 --- 内置的Bean+应用bean
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}

解读prepareBeanFactory

主要工作是添加一些后置处理器。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		//设置 BeanFactory 的类加载器 为当前ApplicationContext的类加载器。
		//用于后面反射获取bean对象。  
		beanFactory.setBeanClassLoader(getClassLoader());
		// 设置Bean 表达是解析器。
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		// 设置后置处理器(可以自己实现)
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		//自定义的Bean对象在实现这些接口时是没有意义的,容器在自动装配时会自动忽略。
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		// 可以自定义实现接口,BeanPostProcess 来实现自己的后置或者前置处理器注册监听
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
---------------------------------
	}

解读 finishBeanFactoryInitialization

执行流程:

  1. 实例化对象
  2. 属性注入
  3. 实现 aware 接口对象的回调
  4. BeanFactoryProcessor对象的before回调
  5. init-method
  6. InitializingBean 接口的回调
  7. BeanFactoryProcessor对象的after回调
  8. context 销毁对象
/**
	 * Finish the initialization of this context's bean factory,
	 * initializing all remaining singleton beans.
	 */
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		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));
		}

		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		
		// 此处是处理循化依赖
		// A对象依赖B,同时B也依赖A
		//1. 在A 完成实例化需要注入B对象
		//2. 发现B对象不存在容器重
		//3. 在实例化B对象
		//4. B对象实例完成后,需要注入A对象
		//5. 此时容器中已经存在A 对象,直接注入
		
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		// 这里开始预初始化singleton beans ,在这个时候不希望在出现bean的定义解析、注册,所以冻结配置
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		//开始实例化Bean对象。
		beanFactory.preInstantiateSingletons();
	}

分析 preInstantiateSingletons 实例化单例bean (DI )
@Override
	public void preInstantiateSingletons() throws BeansException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		//这个是拿到我们所有的Bean名称 在前面创建bean工厂时存放在list中 this.beanDefinitionNames.add(beanName);
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		//	出发初始化所有非懒加载的单例对象
		for (String beanName : beanNames) {
			//获取bean定义对象
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			// factoryBean : 可以看到bean创建的全过程;(自己实例化的对象并且加到beanfactory容器中。特点是:bean创建过程透明)
				if (isFactoryBean(beanName)) {
					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());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					// 重点 : 对于普通的Bean,只要调用 getBean(beanName)就可以初始化
					getBean(beanName);
			------------------------- 调用链start ---------------------------------		
								|
					            | 调用doGetBean()
					            V
             //调用 
               doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
					//检查对象是否创建
					 Object sharedInstance = getSingleton(beanName);
					// 检查bean定义是否在BeanFactory中
					if (parentBeanFactory != null && !containsBeanDefinition(beanName)) 
                    // 检查 标记Bean创建
					if (!typeCheckOnly)  markBeanAsCreated(beanName);
					
					final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
					checkMergedBeanDefinition(mbd, beanName, args);
					//先初始化依赖的Bean
					// 注意: 这里的依赖指的是depends-on 中定义的依赖
					String[] dependsOn = mbd.getDependsOn();
					// 创建单例对象
					if (mbd.isSingleton())return createBean(beanName, mbd, args);
					
								| |
					            | | 调用 createBean() 开始创建bean
					            V V
		protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args){
				RootBeanDefinition mbdToUse = mbd;
				Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
					//准备方法覆盖 (可以对我们的方法进行增强代理)
					mbdToUse.prepareMethodOverrides(); 
					//重头戏
					Object beanInstance = doCreateBean(beanName, mbdToUse, args);
							|	| |
					        |   | | 调用 doCreateBean() 开始创建bean
   					        V   V V
   				
   				// 单例模式 ,移除内存中缓存的单例对象
   			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   			   // 创建对象的包装对象实例
			instanceWrapper = createBeanInstance(beanName, mbd, args);
			// 得到对象实例
			final Object bean = instanceWrapper.getWrappedInstance()	
			...
			// 这一步也很关键,前面都是对象的实例化,这一步负责属性的装配(DI)
			populateBean(beanName, mbd, instanceWrapper);
------------------------------DI START---------------------------------------

自动装配是在什么时候进行的?

自动装配是属性注入的一种。所以自动装配是在属性注入的时候进行。而属性注入是在我们对象实例化之后进行。

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		...
		// 实例的所有属性都在这
		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			// Add property values based on autowire by name if applicable.
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
			// 按照名称装配
				autowireByName(beanName, mbd, bw, newPvs);
			}

			// Add property values based on autowire by type if applicable.
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			// 按照类型装配
			
				autowireByType(beanName, mbd, bw, newPvs);
			}

			pvs = newPvs;
		}

		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

		if (hasInstAwareBpps || needsDepCheck) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			if (hasInstAwareBpps) {
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvs == null) {
							return;
						}
					}
				}
			}
			if (needsDepCheck) {
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}

		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}
------------------------------DI END---------------------------------------
}		-------end ------
					//创建多例对象
					else if (mbd.isPrototype())
			
			}
------------------------- 调用链end ---------------------------------					
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}


小节

Spring 提供了两个后之处理器处理回调监听接口 : BeanPostProcessor;Aware 都是顶级接口。可以用来实现我们的特殊需求。

简述: spring ApplicationContext 流程;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值