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
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;
}