博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring系列之-Spring IOC容器设计:依赖注入设计
阅读量:6563 次
发布时间:2019-06-24

本文共 13656 字,大约阅读时间需要 45 分钟。

hot3.png

一般情况下依赖注入是发生在用户第一次向IOC容器获取bean的过程中,当然也有例外那就是用户设置了lazy-init属性,如果设置了这个属性依赖注入会在bean初始化过程完成,后面我们单独分析这种情况。所有的BeanFactory都会继承一个最基本的BeanFactory,里面有一个最基本的方法getBean(),依赖注入的触发及发生在该方法第一次被调用的时候。我们还是从DefaultListableBeanFactory这个BeanFactory入手。这个类的继承体系还是比较复杂的。

135944_mVXy_2371422.png

其中AbstractBeanFactory中实现了基本的BeanFactory的所有接口,代码中有这么一句注释:Implementation of BeanFactory interface。

//---------------------------------------------------------------------	// Implementation of BeanFactory interface	//---------------------------------------------------------------------	@Override	public Object getBean(String name) throws BeansException {		return doGetBean(name, null, null, false);	}	@Override	public 
T getBean(String name, Class
requiredType) throws BeansException { return doGetBean(name, requiredType, null, false); } @Override public Object getBean(String name, Object... args) throws BeansException { return doGetBean(name, null, args, false); } /** * Return an instance, which may be shared or independent, of the specified bean. * @param name the name of the bean to retrieve * @param requiredType the required type of the bean to retrieve * @param args arguments to use when creating a bean instance using explicit arguments * (only applied when creating a new instance as opposed to retrieving an existing one) * @return an instance of the bean * @throws BeansException if the bean could not be created */ public
T getBean(String name, Class
requiredType, Object... args) throws BeansException { return doGetBean(name, requiredType, args, false); }

获取bean的过程在doGetBean()方法中:

protected 
T doGetBean( final String name, final Class
requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { //将别名转化成bean定义名称 final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. //从缓存中获取单例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 + "'"); } } bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // 如果存在循环引用问题 抛出创建bean异常 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. //从当前缓存中获取不到BeanDefinition就从父级容器中链式查找 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } } //判断是否需要类型验证 if (!typeCheckOnly) { //标记bean已经被创建好了 markBeanAsCreated(beanName); } try { //根据指定Bean名称获取其父级的Bean定义,主要解决Bean继承时子类问题,合并父类公共属性问题 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. //获取到当前bean所依赖的所有bean的名字 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { //Spring 4.0开始对依赖注入的bean进行循环依赖检查,如果需要注入的bean存在循环依赖则抛出异常。 if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } //保存当前bean与需要依赖的bean之间的依赖关系 registerDependentBean(dep, beanName); //递归获取到当前依赖的bean实例 getBean(dep); } } // 创建单例模式的bean实例对象 if (mbd.isSingleton()) { //创建bean单例模式对象,这里采用了一个匿名内部类实现,并且实现了回调,这个方法后续在研究 sharedInstance = getSingleton(beanName, new ObjectFactory
() { @Override public Object getObject() throws BeansException { 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; } } }); //获取bean实例对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //原型模式的bean创建 else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { //回调方法,默认实现是注册当前创建的单例bean为原型对象 beforePrototypeCreation(beanName); //创建置顶bean实例对象 prototypeInstance = createBean(beanName, mbd, args); } finally { //创建完成回调 afterPrototypeCreation(beanName); } //获取给定bean的实例对象 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } //如果创建的bean不是单例也不是原型,则根据bean定义的执行生命周期创建,这里不再继续分析。 else { String scopeName = mbd.getScope(); final 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, new ObjectFactory() { @Override public Object getObject() throws BeansException { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } // Check if required type matches the type of the actual bean instance. if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { try { return getTypeConverter().convertIfNecessary(bean, requiredType); } catch (TypeMismatchException ex) { if (logger.isDebugEnabled()) { logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }

从上面代码可以看出,如果需要创建的是单例的(默认是单例)则从缓存中加载,保证Spring上下文中只有一个实例对象存在,如果内存中不存在则创建并保存在内存中;

如果是原型模式对象,则每次都会创建一个bean对象;

如果均不为上两种则根据bean定义的置顶生命周期创建。

我们主要研究单例bean的创建过程:

sharedInstance = getSingleton(beanName, new ObjectFactory() {						@Override						public Object getObject() throws BeansException {							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;							}						}					});					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

上述代码是bean的实际创建过程,里面用到了一个匿名内部类回调,真正的是:return createBean(beanName, mbd, args);这个方法是一个抽象方法其实现在AbstractAutowireCapableBeanFactory中,其内部实现如下:

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {		if (logger.isDebugEnabled()) {			logger.debug("Creating instance of bean '" + beanName + "'");		}		RootBeanDefinition mbdToUse = mbd;		// Make sure bean class is actually resolved at this point, and		// clone the bean definition in case of a dynamically resolved Class		// which cannot be stored in the shared merged bean definition.		Class
resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { //尝试返回一个代理对象给bean的前后置处理器,这个一会再详细分析 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); //如果返回的对象不为null,直接返回 if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } //创建实例方法 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }

 

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)			throws BeanCreationException {		// Instantiate the bean.		BeanWrapper instanceWrapper = null;		if (mbd.isSingleton()) {            //如果是单例对象先从缓存中找到同名的对象			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);		}		if (instanceWrapper == null) {            //如果缓存中没有遭到则调用createBeanInstance创建bean对应的Java对象实例			instanceWrapper = createBeanInstance(beanName, mbd, args);		}		final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);       //获取实例化对象的类型		Class
beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); mbd.resolvedTargetType = beanType; // 调用后置处理器 synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { 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"); } //防止循环引用尽早持有引用对象 addSingletonFactory(beanName, new ObjectFactory() { @Override public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } // 初始化bean对象 Object exposedObject = bean; try { //属性依赖注入 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { 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); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set
actualDependentBeans = new LinkedHashSet
(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { //注册完成依赖注入的bean registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }

到此IOC依赖注入基本完成。

转载于:https://my.oschina.net/wenbo123/blog/1588617

你可能感兴趣的文章
网络信息安全之防火墙***检测方法 (五)
查看>>
怎样为用户写“招标书”
查看>>
1.7 文件目录管理及相关的命令使用方法
查看>>
实际案例告诉你大数据在农业中如何应用
查看>>
LAMP优化策略
查看>>
PDF中添加页面/合并 PDF 内容
查看>>
JS仿FLASH特效可跳转回首页的CSS二级联动菜单
查看>>
页面导入样式时,使用link和@import有什么区别?
查看>>
类成员与类的实例成员
查看>>
Spark源码编译并在YARN上运行WordCount实例
查看>>
Spring AOP + AspectJ annotation example
查看>>
Spring VS EJB 3 的若干认识误区(转)
查看>>
React.js初探(一)
查看>>
Neo4j CQL -(17)- NULL值
查看>>
BZOJ4554: [Tjoi2016&Heoi2016]游戏 luoguP2825 loj2057
查看>>
json_encode后的中文不编码成unicode
查看>>
iOS 导航栏title显示右偏移
查看>>
修改纵断面图标注栏
查看>>
Flex创建带有空间信息的椭圆(Polygon)
查看>>
【转】参照protobuf,将json数据转换成二进制在网络中传输。
查看>>