本文主要内容及做什么
主要针对spring中的ioc,采用debug方式讲解spring如何创建和获取bean,承接上篇博客解析spring源码,IOC加载bean资源配置文件
test代码为:
public class test {
public static void main(String[] args) {
ApplicationContext cx = new ClassPathXmlApplicationContext("applicationContext.xml");
PersonServiceImpl obj = cx.getBean(PersonServiceImpl.class);
System.out.println(obj.toString());
}
}
getBean方法获取到了一个bean对象,进入其内部,了解其原理,下面debug进入 PersonServiceImpl obj = cx.getBean(PersonServiceImpl.class); 这行代码。
1、进入 cx.getBean() 方法:
public <T> T getBean(Class<T> requiredType) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(requiredType);
}
跳转到了 ClassPathXmlApplicationContext 类的父类 AbstractApplicationContext 中,AbstractApplicationContext 为一个抽象类,AbstractApplicationContext 有多个重载的getBean()方法,其中比较熟悉的最为 getBean(String name) 和 getBean(Class<T> requiredType),分别传参为bean的id和bean对象类的class对象。AbstractApplicationContext 抽象类间接的继承了 BeanFactory 接口,BeanFactory 可以称为spring ioc鼻祖,所有接口、抽象类、普通类都继承了 BeanFactory ,相当于java中的Object类,BeanFactory 接口中定义的方法并不是很多,主要是对bean的操作,有getBean()、containsBean()、isSingleton()等。
2、 getBeanFactory().getBean(requiredType),首先 getBeanFactory() 获取已经创建好的BeanFactory,如果不存在或者关闭则抛出异常。
进入getBean方法,跳转到 DefaultListableBeanFactory 类中:
public <T> T getBean(Class<T> requiredType) throws BeansException {
Assert.notNull(requiredType, "Required type must not be null");
String[] beanNames = getBeanNamesForType(requiredType);
if (beanNames.length > 1) {
ArrayList<String> autowireCandidates = new ArrayList<String>();
for (String beanName : beanNames) {
if (getBeanDefinition(beanName).isAutowireCandidate()) {
autowireCandidates.add(beanName);
}
}
if (autowireCandidates.size() > 0) {
beanNames = autowireCandidates.toArray(new String[autowireCandidates.size()]);
}
}
if (beanNames.length == 1) {
return getBean(beanNames[0], requiredType);
}
else if (beanNames.length > 1) {
T primaryBean = null;
for (String beanName : beanNames) {
T beanInstance = getBean(beanName, requiredType);
if (isPrimary(beanName, beanInstance)) {
if (primaryBean != null) {
throw new NoUniqueBeanDefinitionException(requiredType, beanNames.length,
"more than one 'primary' bean found of required type: " + Arrays.asList(beanNames));
}
primaryBean = beanInstance;
}
}
if (primaryBean != null) {
return primaryBean;
}
throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
}
else if (getParentBeanFactory() != null) {
return getParentBeanFactory().getBean(requiredType);
}
else {
throw new NoSuchBeanDefinitionException(requiredType);
}
}
方法 getBeanNamesForType(requiredType) 返回的是传入类类型已经存在的bean的名字集合,bean的名字即为id,进入getBeanNamesForType()方法可以看到spring使用ArrayList来存放bean名字集合,这里我们只指定了一个bean,所以beanNames的值也只有一个,beanNames.length的值为1。
3、进入 getBean(beanNames[0], requiredType),跳转到 AbstractBeanFactory 抽象类中:
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
再进入
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
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:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationExc