spring容器中所有打了注解的或者在配置文件中被注入成为bean交给spring管理的最后都会在SpringApplication初始化的时候把这些对象都创建一遍,挨个对这些对象进行getBean。
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
Object bean = run.getBean("demo");
}
现在假设整个工厂刚刚启动,里面一个对象也没有,这时就需要在beanDefinitionMap(BeanDefinition中记录了对象的全部信息)取出对象,取出之后进行创建,就到了doGetBean方法。
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
spring创建对象通过反射的方式,因为不能直接获取到类的构造器,创建对象会分为单实例、多实例或其他类型, 默认就是单实例,即Scope为singleton。然后就到了getSingleton(beanName)方法,下面为getSingleton方法的源码:
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
通过反射调用该对象的构造方法,然后把对象创建出来,通过调用addSingleton将创建好的对象放置 在singletonObjects中,然后就会执行createBean和doCreateBean,至此,就创建了一个单例空对象。
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("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);
}
Spring要根据反射获取对象的无参构造函数来创建对象,一定是要根据Class.forName(),来创建对象,所以就需要类的全限定名,上面代码的这个方法就是获取类的全限定名,获取beanDefinition对应的Class对象,有Class就直接返回,没有就根据类的全限定名获取。