1、spring 架構圖
spring IoC:IoC是控制反轉,以前java應用中,對象之間的關係是由代碼直接定義的(應用來管理),現在交給IoC容器來管理,因此叫控制反轉,我們只需要將類定義好,至於類的實例化,以及對象的管理,都交給IoC去管理。舉個例子:對象a 要調用對象b,原本是對象a代碼裏直接寫代碼去調用,但是IoC不是,對象a和對象b都被IoC容器管理着,容器會將b對象的引用傳遞給對象a。所以控制反轉是一個對象如何獲取它所依賴的對象的引用。
spring AOP:面向切面編程。通過AOP聲明的方式,聲明一個代碼段插入另一個代碼段中的哪個位置(只是聲明就能起作用,而不是將代碼段寫進另一個代碼段),然後執行的時候,就能按插入的順序來執行代碼了。直接舉個例子:如果我們代碼都寫完了,這時卻需要添加一段代碼 a 在 已經寫好的代碼 b 之前去執行,要麼我們修改已經寫好的代碼,將a 加到 b 之前,如果我們不修改代碼,那麼此時AOP就起作用了,可以直接將代碼a作一個AOP聲明,聲明它在代碼b之前執行,那麼應用程序在運行時,代碼a就會在代碼b之前運行了。
spring MVC:model 、view 和 controller 三部分。controller:控制層,web請求到後臺時,controller將這個請求下放到具體的處理這個請求的方法; model:模型,處理請求的方法中的邏輯代碼就是模型,負責處理請求; view:視圖,model處理完請求後,可能要返回一些數據給web前端,將要把數據給view,view才能將這些數據處理成展示給用戶看的數據。
spring ORM:spring提供的持久化層,提供接口對數據庫進行操作。
spring 事務處理:事務這個概念就不作介紹了,提供了一系列的事務功能。
spring 遠端調用:spring可以將應用解耦,模塊化。這些模塊可以分佈式地部署,那麼模塊之間需要通信的,spring恰恰對通信和遠端調用作了封裝,因此開發者可以不用去深究通信的細節,也可以靈活地使用不同的通信協議等等。
spring 應用:基於spring開發的各種應用,可以形成一個良好的生態圈,相互之間兼容和協作是比較方便的。
2、IoC容器的設計與實現
在spring IoC容器設計中,主要是兩類容器:實現BeanFactory接口的基礎容器 和 ApplicationContext。
2.1 BeanDefinition 接口
開發者只是定義了開發者角度的bean,但是BeanDefinition 接口還會對bean進行一次抽象封裝,封裝成IoC角度的bean。
BeanDefinition 接口繼承了兩個接口 AttributeAccessor 和 BeanMetadataElement
2.1.1 AttributeAccessor 接口——屬性訪問層
AttributeAccessor接口是用於操作一個屬性隊列的,整個屬性隊列是LinkedHashMap<String, Object>類型,屬性名-屬性值。提供操作整個隊列的一些方法:添加、刪除、獲取、修改、獲取所有屬性名、一個隊列複製到另一個隊列、兩個屬性隊列判等、將整個隊列哈希成一個哈希值。
public interface AttributeAccessor {
void setAttribute(String var1, @Nullable Object var2);//設置屬性,鍵值對的方式
@Nullable
Object getAttribute(String var1);//根據鍵,獲取屬性
@Nullable
Object removeAttribute(String var1); //根據鍵,刪除屬性
boolean hasAttribute(String var1); //根據鍵,判斷屬性是否存在
String[] attributeNames(); //返回所有鍵值
}
//看看這個基本的實現類,就知道屬性訪問機制是怎麼回事了
public abstract class AttributeAccessorSupport implements AttributeAccessor, Serializable {
//這是用於存儲屬性的LinkedHashMap,存儲形式是<屬性名,屬性值>,屬性名不能爲空,屬性值可以爲空
private final Map<String, Object> attributes = new LinkedHashMap();
public AttributeAccessorSupport() {}
//實現setAttribute方法,設置屬性
public void setAttribute(String name, @Nullable Object value) {
Assert.notNull(name, "Name must not be null");//屬性名不能爲空
if (value != null) { //存儲屬性
this.attributes.put(name, value);
} else {
this.removeAttribute(name);
}
}
//根據屬性名獲取屬性值
@Nullable
public Object getAttribute(String name) {
Assert.notNull(name, "Name must not be null");
return this.attributes.get(name);
}
//刪除<屬性名,屬性值>
@Nullable
public Object removeAttribute(String name) {
Assert.notNull(name, "Name must not be null");
return this.attributes.remove(name);
}
//判斷屬性存儲隊列中是否存在此屬性
public boolean hasAttribute(String name) {
Assert.notNull(name, "Name must not be null");
return this.attributes.containsKey(name);
}
//獲取所有屬性名
public String[] attributeNames() {
return StringUtils.toStringArray(this.attributes.keySet());
}
//將另外一個屬性存儲隊列source的內容全部複製到此隊列中
protected void copyAttributesFrom(AttributeAccessor source) {
Assert.notNull(source, "Source must not be null");
String[] attributeNames = source.attributeNames();
String[] var3 = attributeNames;
int var4 = attributeNames.length;
for(int var5 = 0; var5 < var4; ++var5) {
String attributeName = var3[var5];
this.setAttribute(attributeName, source.getAttribute(attributeName));
}
}
//判斷兩個隊列是否相等
public boolean equals(Object other) {
return this == other || other instanceof AttributeAccessorSupport && this.attributes.equals(((AttributeAccessorSupport)other).attributes);
}
//將整個屬性隊列哈希成一個哈希值,並返回哈希值
public int hashCode() {
return this.attributes.hashCode();
}
}