FactoryBean是现在的执行时机
调用getBean方法,最终到org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons方法:
for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) {Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);if (bean instanceof FactoryBean) {FactoryBean<?> factory = (FactoryBean<?>) bean;boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}else {getBean(beanName);}}
}
此处遍历的beanNames就是beanDefinitionNames集合,即按注册顺序排列的 Bean 定义名称列表;
若实现了FactoryBean接口的类,其实现的是SmartFactoryBean并重写isEagerInit()方法,返回true,那么此时就会调用当前实现类的实例化以及初始化;若没返回true,那是执行时机是什么时候呢?
1.在被注入的类中
解析类的时候,会调用org.springframework.beans.factory.annotation.InjectionMetadata.InjectedElement#inject方法,其中回去获取注入的对象,
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor)
最终调用到org.springframework.beans.factory.support.DefaultListableBeanFactory#doGetBeanNamesForType方法,此方法会遍历所有的beanDefinitionNames获取需要注入的对象,并将其放入一个list中返回,最后将其封装为一个map类型(此时key就是实现FactoryBean接口的类名,v就是其bean定义);
if (beanInstance instanceof FactoryBean) {if (!isFactoryDereference) {Class<?> type = getTypeForFactoryBean((FactoryBean<?>) beanInstance);return (type != null && typeToMatch.isAssignableFrom(type));}else {return typeToMatch.isInstance(beanInstance);}
}
即通过此处调用FactoryBean的getObjectType方法进行对比;
2)获取到map进行校验
for (Map.Entry<String, Object> entry : candidates.entrySet()) {String candidateName = entry.getKey();Object beanInstance = entry.getValue();if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||matchesBeanName(candidateName, descriptor.getDependencyName())) {return candidateName;}}
最后获取到bean的名称,调用getBean方法,其中在获取到对象后,会调用如下方法:
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
其中就是判断此对象是否实现了FactoryBean接口,若实现了,则会返回getObject创建的对象;
至此,解析结束。