看了《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()
使用的是cglib的enhancer类来创建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