spring扩展点-FactoryBean

FactoryBean也是我们向spring容器注入Bean常用手段,这种方式有如下特点:

    a. 延迟加载,只有注入的Bean(T)被依赖时,才会调用getObject方法,首次使用才会调用,此后会从缓存中读取(FactoryBeanRegistrySupport.factoryBeanObjectCache缓存)

    b. 这种方式会创建两个对象,一个是FactoryBean类型,另一个是自定义类型(泛型类型)

    c. 这种方式通常用来注入一些实例化比较复杂的对象

下面让我们来看一下如何使用吧,我们使用这种方式向spring容器注入UserFactoryBean对象:

1. 定义一个要注入的类

/**
 * 测试FactoryBean接口向spring容器注入Bean
 *
 */
public class UserFactoryBean {
	
	private String name;
	
	public UserFactoryBean() {}
	
	public UserFactoryBean(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

2. 定义一个FactoryBean接口实现类

@Configuration
public class MyFactoryBean implements FactoryBean {

	@Override
	public UserFactoryBean getObject() throws Exception {
		UserFactoryBean u = new UserFactoryBean();
		u.setName("张三");
		return u;
	}

	@Override
	public Class getObjectType() {
		return UserFactoryBean.class;
	}

}

3. 测试类

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class BaseTest {

	@Autowired
	private UserFactoryBean userFactoryBean;
	
	@Test
	public void testFactoryBean() {
		if (null != userFactoryBean) {
			System.out.println(userFactoryBean.getName());
		}
	}
}

4. 测试结果

张三

5. 源码分析

5.1 实例化MyFactoryBean

/**
 * GenericWebApplicationContext(AbstractApplicationContext)
 */
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		prepareBeanFactory(beanFactory);

		try {
			......
			// Instantiate all remaining (non-lazy-init) singletons.
			finishBeanFactoryInitialization(beanFactory);
			......
		}

		catch (BeansException ex) {
			......
		}

		finally {
			......
		}
	}
}

/**
 * GenericWebApplicationContext(AbstractApplicationContext)
 */
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	......
	// Instantiate all remaining (non-lazy-init) singletons.
	beanFactory.preInstantiateSingletons();
}

/**
 * DefaultListableBeanFactory
 */
public void preInstantiateSingletons() throws BeansException {
	if (this.logger.isDebugEnabled()) {
		this.logger.debug("Pre-instantiating singletons in " + this);
	}

	// Iterate over a copy to allow for init methods which in turn register new bean definitions.
	// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
	List beanNames = new ArrayList<>(this.beanDefinitionNames);

	// 实例化所有非懒初始化类(默认lazyInit=false,可以通过添加@Lazy注解或在Bean标签设置lazy-init="true")
	for (String beanName : beanNames) {
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			if (isFactoryBean(beanName)) {
				// 如果是FactoryBean,就初始化,注意此处方法参数为&+beanName,这时实例化的是FactoryBean本身
				Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
				if (bean instanceof FactoryBean) {
					final FactoryBean factory = (FactoryBean) bean;
					boolean isEagerInit;
					// 如果bean是FactoryBean类型,且实现了SmartFactoryBean接口,就判断是否需要进一步实例化自定义对象(调用getObject())
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
						isEagerInit = AccessController.doPrivileged((PrivilegedAction)
										((SmartFactoryBean) factory)::isEagerInit,
								getAccessControlContext());
					}
					else {
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean) factory).isEagerInit());
					}
					// 如果是懒加载,就不初始化
					if (isEagerInit) {
						getBean(beanName);
					}
				}
			}
			// 如果不是FactoryBean类型,就直接初始化
			else {
				getBean(beanName);
			}
		}
	}

	// Trigger post-initialization callback for all applicable beans...
	for (String beanName : beanNames) {
		// 如果bean是SmartInitializingSingleton类型,就调用afterSingletonsInstantiated方法
		Object singletonInstance = getSingleton(beanName);
		if (singletonInstance instanceof SmartInitializingSingleton) {
			final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged((PrivilegedAction) () -> {
					smartSingleton.afterSingletonsInstantiated();
					return null;
				}, getAccessControlContext());
			}
			else {
				smartSingleton.afterSingletonsInstantiated();
			}
		}
	}
} 
  

5.2 实例化UserFactoryBean

spring容器默认不会主动实例化UserFactoryBean对象(调用getObject方法),如果有此需求,要实现SmartFactoryBean接口,当自定义对象(UserFactoryBean)第一次被别的类依赖时,会调用getObject方法,并保存在FactoryBeanRegistrySupport.factoryBeanObjectCache缓存中,下面看一下源码分析:

/**
 * 给对象成员变量赋值
 * DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory)
 */
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

	......
	PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

	// 如果设置了byName或byType,就进行相应处理
	if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
			mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

		// Add property values based on autowire by name if applicable.
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
			autowireByName(beanName, mbd, bw, newPvs);
		}

		// Add property values based on autowire by type if applicable.
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			autowireByType(beanName, mbd, bw, newPvs);
		}

		pvs = newPvs;
	}

	boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
	boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

	if (hasInstAwareBpps || needsDepCheck) {
		if (pvs == null) {
			pvs = mbd.getPropertyValues();
		}
		PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
		if (hasInstAwareBpps) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					// 其中AutowiredAnnotationBeanPostProcessor会用byType方式注入依赖
					pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvs == null) {
						return;
					}
				}
			}
		}
		if (needsDepCheck) {
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}
	}

	// 对象的成员变量赋值
	if (pvs != null) {
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
}

/**
 * AutowiredAnnotationBeanPostProcessor
 */
public PropertyValues postProcessPropertyValues(
		PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {

	// 查找bean所在类的Field和Method上被@Autowired、@Value、@Inject注解注入的对象
	InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
	try {
		metadata.inject(bean, beanName, pvs);
	}
	catch (BeanCreationException ex) {
		throw ex;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
	}
	return pvs;
}

/**
 * InjectionMetadata
 */
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
	Collection checkedElements = this.checkedElements;
	Collection elementsToIterate =
			(checkedElements != null ? checkedElements : this.injectedElements);
	if (!elementsToIterate.isEmpty()) {
		boolean debug = logger.isDebugEnabled();
		for (InjectedElement element : elementsToIterate) {
			if (debug) {
				logger.debug("Processing injected element of bean '" + beanName + "': " + element);
			}
			element.inject(target, beanName, pvs);
		}
	}
}

/**
 * AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement
 * @param bean
 * @param beanName
 * @param pvs
 * @throws Throwable
 */
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
	Field field = (Field) this.member;
	Object value;
	if (this.cached) {
		value = resolvedCachedArgument(beanName, this.cachedFieldValue);
	}
	else {
		DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
		desc.setContainingClass(bean.getClass());
		Set autowiredBeanNames = new LinkedHashSet<>(1);
		Assert.state(beanFactory != null, "No BeanFactory available");
		TypeConverter typeConverter = beanFactory.getTypeConverter();
		try {
			// 调用beanFactory的resolveDependency方法
			value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
		}
		catch (BeansException ex) {
			throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
		}
	}
}

/**
 * DefaultListableBeanFactory
 */
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
		@Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

	InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
	try {

		Class type = descriptor.getDependencyType();
		......
		// 根据注入类型查询
		Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
		if (matchingBeans.isEmpty()) {
			if (isRequired(descriptor)) {
				raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
			}
			return null;
		}

		String autowiredBeanName;
		Object instanceCandidate;

		// 如果查询多个符合条件bean,就进一步进行过滤
		if (matchingBeans.size() > 1) {
			autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
			if (autowiredBeanName == null) {
				if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
					return descriptor.resolveNotUnique(type, matchingBeans);
				}
				else {
					// In case of an optional Collection/Map, silently ignore a non-unique case:
					// possibly it was meant to be an empty collection of multiple regular beans
					// (before 4.3 in particular when we didn't even look for collection beans).
					return null;
				}
			}
			instanceCandidate = matchingBeans.get(autowiredBeanName);
		}
		else {
			// We have exactly one match.
			Map.Entry entry = matchingBeans.entrySet().iterator().next();
			autowiredBeanName = entry.getKey();
			instanceCandidate = entry.getValue();
		}

		if (instanceCandidate instanceof Class) {
			instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
		}
		Object result = instanceCandidate;
		if (result instanceof NullBean) {
			if (isRequired(descriptor)) {
				raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
			}
			result = null;
		}
		if (!ClassUtils.isAssignableValue(type, result)) {
			throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
		}
		return result;
	}
	finally {
		ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
	}
}

/**
 * DefaultListableBeanFactory
 */
protected Map findAutowireCandidates(
		@Nullable String beanName, Class requiredType, DependencyDescriptor descriptor) {

	// 根据类型从beanDefinitionNames查询符合条件的bean name集合,没有实例化的bean,根据beanDedifinition的beanClass属性判断
	String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
			this, requiredType, true, descriptor.isEager());
	Map result = new LinkedHashMap<>(candidateNames.length);
	// 判断所需类型是否是spring系统内置对象,比如BeanFactory、ApplicationContext、ServletRequest等
	for (Class autowiringType : this.resolvableDependencies.keySet()) {
		if (autowiringType.isAssignableFrom(requiredType)) {
			Object autowiringValue = this.resolvableDependencies.get(autowiringType);
			autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
			if (requiredType.isInstance(autowiringValue)) {
				result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
				break;
			}
		}
	}
	// 遍历上面查询到的candidateNames
	for (String candidate : candidateNames) {
		if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
		    // 调用getBean(beanName)获取对应的实例(没有会直接实例化),对于FactoryBean自定义类型,这里会调用getObject方法,并放到缓存中
			addCandidateEntry(result, candidate, descriptor, requiredType);
		}
	}
	......
	return result;
}

 

你可能感兴趣的:(spring,spring-boot,spring,扩展点)