一:doGetBean方法
1.判断beanName是否为空,为空抛异常,再判断beanName是否以&开头是的话去掉&。
2.执行getSingleton(beanName),获取bean的登记式单例,如果需要的单例不为空的话返回已存在的单例。(返回语句在方法结尾处)
if ((sharedInstance != null) && (args == null)) {
if (this.logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
this.logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
}
else{
this.logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
3.未获取到单例的话去获取bean的beanDefination,如果beanDefination中不存在指定bean的beanDefination并且父级容器不为空则去父级容器中请求bean
if ((parentBeanFactory != null) && (!containsBeanDefinition(beanName)))
{
String nameToLookup = originalBeanName(name);
if (args != null)
{
return parentBeanFactory.getBean(nameToLookup, args);
}
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
4.获取当前请求的bean所依赖的所有bean名称,不为空的话去递归调用getBean方法
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (int i = 0; i < dependsOn.length; i++) {
String dependsOnBean = dependsOn[i];
getBean(dependsOnBean);
registerDependentBean(dependsOnBean, beanName);
}
}
5.如果是单例模式创建单例模式的bean,如果是原型模式创建原型模式的bean,否则根据bean定义资源中配置的生命周期范围实例化bean。
web应用程序中比较常用,比如request,session,application等生命周期。
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
try {
return AbstractBeanFactory.this.createBean(beanName, mbd, args);
}
catch (BeansException ex)
{
AbstractBeanFactory.this.destroySingleton(beanName);
throw ex;}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype())
{
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else
{
String scopeName = mbd.getScope();
Scope scope = (Scope)this.scopes.get(scopeName);
if (scope == null)
throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
try
{
Object scopedInstance = scope.get(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
AbstractBeanFactory.this.beforePrototypeCreation(beanName);
try {
return AbstractBeanFactory.this.createBean(beanName, mbd, args);
}
finally {
AbstractBeanFactory.this.afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
二:doCreateBean方法(AbstractAutowireCapableBeanFactory)
1.用beanName和beanDefination为参数创建实例对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
三种方式实例化:
1》.如果rootBeanDefination的工厂方法名不为空,用工厂方法模式创建实例。
if (mbd.getFactoryMethodName() != null) {
2》.如果方法传进来的参数args不为空使用自动装配方式实例化,容器的自动装配是根据参数类型匹配bean的构造方法。
要想不为空,从getBean开始就得传
3》.使用默认的无参构造方法实例化bean
此方式最常用:beandefination判断MethodOverrides()类中hashset集合性质的一个属性中维护的MethodOverride类是否为空,为空的话用反射机制来实例化,否则用CGLIB动态代理技术来进行实例化。
2.初始化bean对象,依赖注入在此触发
exposedObject 在初始化完成后返回作为依赖注入完成后的bean
Object exposedObject = bean;
try {
将bean实例对象封装,并且将bean定义中配置的属性值赋值实例对象
populateBean(beanName, mbd, instanceWrapper);
初始化bean对象
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
http://www.cnblogs.com/davidwang456/p/4192318.html (BeanDefination是接口)
populateBean()方法:填充bean
1》.获取容器解析bean定义资源时给beanDefination设置的属性值
PropertyValues pvs = mbd.getPropertyValues();
2》.设置属性前先调用后置处理器
http://www.cnblogs.com/sishang/p/6576665.html(后置处理器:如果要在bean实例化、初始化前后加一些自己的逻辑处理,需要定义一个或多个BeanPostProcessor的实现类来,然后注册到IOC容器中。)
3》.首先处理autoaire自动装配的注入
使用取得的当前Bean的属性名作为Bean的名字,向IoC容器getBean ,然后把从容器得到的Bean设置(setPropertyValues)到当前Bean的属性中去
4》.解析
判断属性值是否需要解析,比如属性值为另一个bean的引用,需要先解析再注入
5》.注入:依赖注入的过程就是将bean对象实例设置到它依赖的bean对象属性上去。