梳理Spring获取Bean的流程
Spring获取Bean的方法在接口BeanFactory中定义
public interface BeanFactory {
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
}
可以根据Bean的名称或者类型获取。我们今天只看根据类型获取的逻辑,即下面的方法定义
<T> T getBean(Class<T> requiredType) throws BeansException;
我们首先写一段常规初始化工厂和获取Bean的代码
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Smile smile = context.getBean(Smile.class);
smile.smile("hh");
AnnotationConfigApplicationContext extends GenericApplicationContext extends AbstractApplicationContext
在AbstractApplicationContext类中实现了BeanFactory中定义的getBean方法
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(requiredType);
}
该类又将获取Bean的具体操作交给getBeanFactory()返回的类来实现。我们看下getBeanFactory()方法的定义
@Override
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
该方法是抽象方法,需要子类去实现。在我们当前的示例中,子类为GenericApplicationContext。GenericApplicationContext实现了getBeanFactory()方法
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
return this.beanFactory;
}
返回一个成员变量,这个成员变量的类型为
private final DefaultListableBeanFactory beanFactory;
所以我们获取Bean的逻辑转到了DefaultListableBeanFactory类中
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
return getBean(requiredType, (Object[]) null);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {
Assert.notNull(requiredType, "Required type must not be null");
Object resolved = resolveBean(ResolvableType.forRawClass(requiredType), args, false);
if (resolved == null) {
throw new NoSuchBeanDefinitionException(requiredType);
}
return (T) resolved;
}
可以看到获取Bean的逻辑主要在resolveBean方法中,我们接着看resolveBean方法
@Nullable
private <T> T resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) {
NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args, nonUniqueAsNull);
if (namedBean != null) {
return namedBean.getBeanInstance();
}
BeanFactory parent = getParentBeanFactory();
if (parent instanceof DefaultListableBeanFactory) {
return ((DefaultListableBeanFactory) parent).resolveBean(requiredType, args, nonUniqueAsNull);
}
else if (parent != null) {
ObjectProvider<T> parentProvider = parent.getBeanProvider(requiredType);
if (args != null) {
return parentProvider.getObject(args);
}
else {
return (nonUniqueAsNull ? parentProvider.getIfUnique() : parentProvider.getIfAvailable());
}
}
return null;
}
我们只关注方法的前四行,resolveNamedBean方法根据Class信息获取Bean名称,然后将获取Bean的逻辑交给了下面的方法
public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
throws BeansException {
return doGetBean(name, requiredType, args, false);
}
该方法在AbstractBeanFactory类中定义,真正的获取Bean的逻辑在doGetBean方法中,在doGetBean方法中真正获取Bean的逻辑在getSingleton方法中,该方法在DefaultSingletonBeanRegistry类中,定义如下
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {}