IOC作爲Spring的核心功能其核心思想:
幫用戶管理對象,對象的創建不需要再由應用實現,而是交給了spring來管理。也就是對象的控制交給了第三方,也就是控制反轉的由來。
下面是Spring IOC核心工廠類的結構圖
從這個類結構圖我們可以看出DefaultListableBeanFactory實現了哪些功能
1、 是一個BeanDefinition註冊器
2、 最重要的它是一個bean工廠
3、 它是一個別名註冊器
4、 他是一個單例對象註冊器
BeanDefinition
通過解析Xml或者註解掃描獲取到的目標對象的屬性,spring根據這個對象通過反射機制來創建目標對象。我們可以看看BeanDefinition接口的一個重要方法
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
String getBeanClassName();
void setBeanClassName(String beanClassName);
}
實現這個接口的肯定會提供類全限定名屬性,spring可以通過全限定名反射並實例化對象。
Alias
spring可以實現一個Bean對象有多個別名
<bean id="pos" class="com.yanlink.chapter4.alias.Pos">
<property name="name" value="密碼鍵盤"/>
</bean>
<alias name="pos" alias="pax"/>
<alias name="pos" alias="box"/>
Pos pos1 = (Pos) beanFactory.getBean("pax");
pos1 = (Pos) beanFactory.getBean("box");
兩次獲取的對象是同一個對象。
我們看看別名的實現類
public class SimpleAliasRegistry implements AliasRegistry {
/** Map from alias to canonical name */
private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>(16);
public void registerAlias(String name, String alias) {
if (alias.equals(name)) {
// 如果別名和本名一樣,則不需要添加別名機制
this.aliasMap.remove(alias);
}
else {
this.aliasMap.put(alias, name);
}
}
我們看到了註冊別名的時候其實就是往一個Map對象中添加別名映射的實際對象名。在使用的時候會再根據別名找到實際對象名。
BeanFactory
我們看看BeanFactory接口
public interface BeanFactory {
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
}
這裏接口定義了通過各種方式獲取Bean的方法,這裏面的細節單獨需要一個章節來講解,這裏我們只要知道DefaultListableBeanFactory是一個工廠就可以了,這裏使用了工廠方法的設計模式,定義創建產品的方法,具體實現交給子類處理。
SingletonBeanRegistry
spring管理的主要還是Scope爲Singleton類型的Bean,這個接口就是針對創建的Singleton的bean對象的管理。
先來看看其接口
public interface SingletonBeanRegistry {
// 註冊singleton對象
void registerSingleton(String beanName, Object singletonObject);
// 獲取singleton對象
Object getSingleton(String beanName);
boolean containsSingleton(String beanName);
String[] getSingletonNames();
int getSingletonCount();
}
從這個接口可以看出來,spring創建的bean如果是singleton是需要被管理起來的,我們來看看其實現
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/**
* Internal marker for a null singleton object:
* used as marker value for concurrent Maps (which don't support null values).
*/
protected static final Object NULL_OBJECT = new Object();
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
/** Set of registered singletons, containing the bean names in registration order */
private final Set<String> registeredSingletons = new LinkedHashSet<String>(64);
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
addSingleton(beanName, singletonObject);
}
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 向singletonObjects中添加對象,如果添加的是null,則向singletonObjects中添加NULL_OBJECT
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 從singletonObjects獲取對象
Object singletonObject = this.singletonObjects.get(beanName);
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
protected void removeSingleton(String beanName) {
synchronized (this.singletonObjects) {
this.singletonObjects.remove(beanName);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.remove(beanName);
}
}
}
從這個實現看出來spring創建的對象如果是singleton的,將會保存在一個ConcurrentHashMap中緩存起來,多次獲取同一名稱的對象spring返回的是同一個對象,所以Singleton在spring中表現爲單例形式的對象。
singleton相關的可不僅僅是緩存單例對象,它還解決了一個比較重要的問題循環依賴,這個我也分一個小章節來講解。
總結:
今天這篇文章簡單地介紹了Spring的核心類DefaultListableBeanFactory是什麼
1、它是一個BeanDefinition註冊器
2、它是一個Bean工廠
3、它是一個別名註冊器
4、它是一個Singleton註冊器