版權聲明
- 本文原創作者:谷哥的小弟
- 作者博客地址:http://blog.csdn.net/lfdfhl
1. BeanFactory 概述
BeanFactory
是 Spring IoC 容器的最基礎接口,它定義了獲取、配置和管理 Bean 的核心方法。它是 Spring 框架中容器體系的頂層接口之一,提供了最基本的依賴注入功能。
1.1 接口定義
public interface BeanFactory {String FACTORY_BEAN_PREFIX = "&";Object getBean(String name) throws BeansException;<T> T getBean(String name, Class<T> requiredType) throws BeansException;<T> T getBean(Class<T> requiredType) throws BeansException;boolean containsBean(String name);boolean isSingleton(String name) throws BeansException;boolean isPrototype(String name) throws BeansException;boolean isTypeMatch(String name, ResolvableType typeToMatch) throws BeansException;Class<?> getType(String name) throws BeansException;String[] getAliases(String name);
}
getBean
:獲取容器中已注冊的 Bean 實例。containsBean
:判斷某個名稱的 Bean 是否存在。isSingleton
/isPrototype
:判斷 Bean 的作用域。getType
/isTypeMatch
:獲取或匹配 Bean 的類型。getAliases
:獲取某個 Bean 的所有別名。
1.2 與 ApplicationContext 的關系
BeanFactory
是 Spring 容器的基礎接口。ApplicationContext
是其子接口,擴展了BeanFactory
的功能,增加了國際化、事件發布、資源加載等高級功能。BeanFactory
是“按需加載”,而ApplicationContext
是“預加載單例 Bean”。
2. 核心實現類
DefaultListableBeanFactory
是 Spring 中最常用的 BeanFactory
實現類,它實現了 BeanDefinitionRegistry
接口,支持注冊和管理 Bean 定義。
2.1. 核心屬性
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactoryimplements ConfigurableListableBeanFactory, BeanDefinitionRegistry {private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
}
beanDefinitionMap
:存儲 Bean 名稱與BeanDefinition
的映射關系。beanDefinitionNames
:存儲所有已注冊的 Bean 名稱列表。
2.2 注冊 Bean 定義
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException {this.beanDefinitionMap.put(beanName, beanDefinition);if (!this.beanDefinitionNames.contains(beanName)) {this.beanDefinitionNames.add(beanName);}
}
- 將 Bean 定義放入
beanDefinitionMap
中。 - 將 Bean 名稱加入
beanDefinitionNames
列表。
3. Bean 的加載過程
getBean()
是獲取 Bean 的核心方法。其調用鏈如下:
getBean()
→ doGetBean()
→ getSingleton()
→ createBean()
→ doCreateBean()
→ populateBean()
→ initializeBean()
3.1 doGetBean()
方法
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {final String beanName = transformedBeanName(name);Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {// 如果是 FactoryBean,處理 & 前綴bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);} else {// 創建 Beanbean = createBean(beanName, mbd, args);}return (T) bean;
}
transformedBeanName
:處理&
前綴(用于獲取 FactoryBean 本身)。getSingleton
:嘗試從單例緩存中獲取 Bean。createBean
:如果不存在,調用createBean
創建新實例。
3.2 單例 Bean 的創建
3.2.1 getSingleton()
方法
public Object getSingleton(String beanName) {return this.singletonObjects.get(beanName);
}
singletonObjects
:是一個Map<String, Object>
,緩存所有已創建的單例 Bean。
3.2.2 創建 Bean 的流程
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {// 1. 解析 Bean 的 ClassClass<?> resolvedClass = resolveBeanClass(mbd, beanName);// 2. 實例化 BeanObject beanInstance = instantiateBean(beanName, mbd);// 3. 屬性注入populateBean(beanName, mbd, instanceWrapper);// 4. 初始化 BeanexposedObject = initializeBean(beanName, exposedObject, mbd);// 5. 注冊為單例addSingleton(beanName, exposedObject);return exposedObject;
}
4. Bean 的生命周期
Spring 中 Bean 的生命周期由 BeanFactory
管理,其流程如下:
- 實例化:通過構造方法或工廠方法創建 Bean 實例。
- 屬性注入:注入依賴的其他 Bean 或配置值。
- 初始化前回調:如
BeanNameAware
、BeanFactoryAware
等接口的回調。 - 初始化方法調用:如
@PostConstruct
、InitializingBean
接口或配置的init-method
。 - 使用 Bean:Bean 可以被使用。
- 銷毀前回調:如
@PreDestroy
、DisposableBean
接口或配置的destroy-method
。 - 銷毀 Bean:清理資源。
初始化 Bean 示例如下:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {// 調用 Aware 接口方法invokeAwareMethods(beanName, bean);// 調用初始化方法if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}invokeInitMethods(beanName, wrappedBean, mbd);if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;
}
5. 工廠 Bean(FactoryBean)
FactoryBean
是一種特殊的 Bean,它本身是一個工廠,用于創建其他 Bean。
5.1 接口定義
public interface FactoryBean<T> {T getObject() throws Exception;Class<?> getObjectType();boolean isSingleton();
}
5.2 獲取 FactoryBean 實例
Object bean = getBean("&myFactoryBean");
assertTrue(bean instanceof FactoryBean);
- 使用
&
前綴獲取 FactoryBean 本身。 - 不帶前綴則獲取其
getObject()
返回的 Bean。
6. Bean 的作用域(Scope)
Spring 支持多種作用域,包括:
- singleton(默認):每個容器中只有一個實例。
- prototype:每次調用
getBean()
都返回一個新實例。 - request / session(Web 作用域):每個請求或會話一個實例。
作用域實現機制如下:
public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {String beanName = transformedBeanName(name);RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);return mbd.isSingleton();
}
RootBeanDefinition
中保存了 Bean 的作用域配置。
7. BeanFactory 的擴展機制
7.1 BeanFactoryPostProcessor
允許在 Bean 實例化之前修改 BeanDefinition
。
public interface BeanFactoryPostProcessor {void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
示例:
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {BeanDefinition beanDef = beanFactory.getBeanDefinition("myBean");beanDef.setScope(BeanDefinition.SCOPE_PROTOTYPE);}
}
7.2 BeanPostProcessor
允許在 Bean 實例化前后進行干預。
public interface BeanPostProcessor {default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
}
8. BeanFactory 與 ApplicationContext 的對比
特性 | BeanFactory | ApplicationContext |
---|---|---|
初始化時機 | 按需加載(懶加載) | 啟動時預加載單例 Bean |
功能特性 | 僅提供基本的依賴注入 | 提供國際化、事件發布、資源加載等高級功能 |
資源加載 | 僅支持類路徑加載 | 支持多種資源加載方式(如 Ant 路徑) |
擴展點支持 | 需手動注冊 BeanPostProcessor 等組件 | 自動注冊并調用擴展點 |
9. 核心代碼示例與解釋
9.1 手動注冊 Bean 定義并獲取 Bean
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
RootBeanDefinition definition = new RootBeanDefinition(MyBean.class);
factory.registerBeanDefinition("myBean", definition);MyBean bean = factory.getBean("myBean", MyBean.class);
System.out.println(bean);
- 創建
DefaultListableBeanFactory
。 - 定義
BeanDefinition
。 - 注冊 Bean 定義。
- 獲取 Bean 實例。
9.2 使用 BeanFactoryPostProcessor
修改 Bean 定義
factory.addBeanPostProcessor(new CustomBeanFactoryPostProcessor());
- 將自定義的
BeanFactoryPostProcessor
添加到容器中。
10. 總結
BeanFactory
是 Spring IoC 容器的核心接口之一,它提供了最基本的依賴注入功能。其設計體現了模塊化、可擴展性和靈活性,是構建 Spring 容器體系的基礎。通過理解其源碼結構、生命周期管理、Bean 加載機制以及擴展機制,開發者可以更深入地掌握 Spring 的運行原理,并在實際項目中更好地進行配置和優化。實踐建議如下:
- 優先使用
ApplicationContext
:在企業級應用中推薦使用,因其提供了更全面的功能。 - 理解
BeanFactory
的懶加載機制:適用于資源受限的場景。 - 合理使用
BeanPostProcessor
和BeanFactoryPostProcessor
:用于擴展容器行為。 - 避免過度依賴
BeanFactory
的底層 API:保持代碼的可測試性和可維護性。