Spring IoC依赖注入的实现

看了《spring技术内幕》的第二章,学习了spring的IoC容器的实现,对其做了浅显地分析。

依赖注入的时机:如果配置文件有配置lazy-init,那么依赖注入的时机发生在用户向IoC

容器索取bean的时候,即调用beanfactory的getBean()方法的时候。

DefaultListerableBeanFactory的基类AbstractBeanFactory实现了getBean()方法。

getBean()有4种重载的方式:

public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}
	public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
		return doGetBean(name, requiredType, null, false);
	}
	public Object getBean(String name, Object... args) throws BeansException {
		return doGetBean(name, null, args, false);
	}
public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
		return doGetBean(name, requiredType, args, false);
	}

无一例外地调用了doGetBean()这个方法。

doGetBean()方法实现分析如下:

doGetBean()仍然在AbstractBeanFactory这个类中。处理流程如下:

1.      先从缓存中去取,处理已经被创建过的单例模式的bean

Object sharedInstance = getSingleton(beanName);

2.      创建bean。

如果为singleTon

if (mbd.isSingleton()) {
				sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
					public Object getObject() throws BeansException {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							destroySingleton(beanName);
							throw ex;
						}
					}
				});
				bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}

如果为Prototype

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);
				}
				bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}

doGetBean()方法实际上调用了createBean()这个方法来创建bean。

CreateBean()方法在AbstractAutowireCapableBeanFactory这个类中实现:

Object beanInstance = doCreateBean(beanName, mbd, args);
doCreateBean()这个方法如下
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args){
BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
……

createBeanInstance()的实现:

createBeanInstance()这个方法仍然写在AbstractAutowireCapableBeanFactory这个类中,调用了instantiateBean()这个方法来创建bean

instantiateBean()这个方法实现如下

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			if (System.getSecurityManager() != null) {
				beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
					public Object run() {
						return getInstantiationStrategy().instantiate(mbd, beanName, parent);
					}
				}, getAccessControlContext());
			}
			else {
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}


注意

beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);

使用策略来进行初始化,getInstantiationStrategy()

protected InstantiationStrategy getInstantiationStrategy() {
		return this.instantiationStrategy;
	}

instantiationStrategy在初始化的时候就写好了,

private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();

spring中默认的生成bean对象是cglib库。还又另外一种方法就是jdk中的反射功能。

Class.forName().newInstance()

使用的是cglibenhancer类来创建bean

public Object instantiate(Constructor ctor, Object[] args) {
			Enhancer enhancer = new Enhancer();
			enhancer.setSuperclass(this.beanDefinition.getBeanClass());
			enhancer.setCallbackFilter(new CallbackFilterImpl());
			enhancer.setCallbacks(new Callback[] {
					NoOp.INSTANCE,
					new LookupOverrideMethodInterceptor(),
					new ReplaceOverrideMethodInterceptor()
			});

			return (ctor == null) ? 
					enhancer.create() : 
					enhancer.create(ctor.getParameterTypes(), args);
		}

整个调用图用下图来分析即可




做个标记

http://h-eaven.iteye.com/blog/1161979

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值