FactoryBean是现在的执行时机

时间:2023-01-16 01:20:12

调用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);
	}
}

即通过此处调用FactoryBeangetObjectType方法进行对比;

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创建的对象;

至此,解析结束。