- 加載配置檔案
- 解析
- 封裝成 BeanDefinition 對象
- 執行個體化
- 完整對象
- 使用
讀取各種形式比如 json、注解、xml 的配置,就通過BeanDefinitionReader 讀取。并非直接反射BeanDefinition注入值得到對象,否則 Spring 毫無意義。
BeanFactory
等同于容器。
何時使用FactoryBean?
FactoryBean是一個工廠Bean,可生成某一個類型的Bean執行個體。
最大作用:讓我們能夠自定義Bean的建立過程。
而在BeanFactory中可建立和管理Spring容器中的Bean,它對Bean的建立有一個統一的流程。
1 FactoryBean
定義
- 泛型接口

API
- 傳回Bean對象執行個體
- Bean類型
- 是否單例。true是單例,false是非單例 。在Spring5.x利用Java8新特性變成default方法,傳回true
2 使用FactoryBean
//FactoryBean接口實作類
@Component
public class FactoryBeanLearn implements FactoryBean {
@Override
public Object getObject() throws Exception {
// 自己new,這裡就可以控制Bean的建立過程
return new FactoryBeanServiceImpl();
}
@Override
public Class<?> getObjectType() {
return FactoryBeanService.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
接口
public interface FactoryBeanService {
/**
* 測試FactoryBean
*/
void testFactoryBean();
}
//實作類
public class FactoryBeanServiceImpl implements FactoryBeanService {
@Override
public void testFactoryBean() {
System.out.println("我是FactoryBean的一個測試類。。。。");
}
}
測試類
@Test
public void test() {
ClassPathXmlApplicationContext cac = new ClassPathXmlApplicationContext("classpath:com/javaedge/applicationContext.xml");
FactoryBeanService beanService = cac.getBean(FactoryBeanService.class);
beanService.testFactoryBean();
}
從Spring容器中擷取了FactoryBeanService類型的Bean。那麼這個擷取Bean的過程Spring是怎麼處理的呢?它是怎麼從FactoryBean中擷取我們自己建立的Bean執行個體的呢?
先從getBean這個方法看起,在Spring的AbstractApplicationContext中有很多重載的getBean方法,這裡調用根據Type(Class類型)來擷取的Bean資訊。我們傳入type是FactoryBeanService類型。
getBean
AbstractApplicationContext#getBean(java.lang.Class)
resolveBean
@Nullable
private <T> T resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) {
// 解析Bean
NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args, nonUniqueAsNull);
if (namedBean != null) {
return namedBean.getBeanInstance();
}
// 如果目前Spring容器中沒擷取到對應Bean資訊,則從父容器擷取
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;
}