Spring
首先它是一個開源而輕量級的框架。其核心容器的主要組件是Bean工廠(BeanFactory)。Bean工廠使用控制反轉(IOC)模式來降低程序代碼之間的耦合度,並提供了面向切面編程(AOP)的實現。
正如其字面意思,是程序員的春天,大大地降低了體力勞動~
Spring 常用注解
1、@Component : 組件。標識這是個受 spring 管理的組件。(當組件不好歸類時使用)
2、@Controller:用於標注控制層組件(如 struts 中的 action)。
使用這個注解,且不指定 value 的時候,默認 bean 的名字為類名首字母小寫。
3、@Service:用於標注業務層組件。
4、@Repository:用於標注數據訪問組件,即DAO組件。
5、@Scope("prototype") :將Action的范圍設置為原型(也就是多例的)。保證每一個請求有一個單獨的 Action 來處理,避免 struts 中 Action 的線程問題。
由於 spring 默認是單例的,這種情況下,只會創建一個 Action 對象,每次訪問都是同一個對象,數據不安全。Struts 要求必須是多例的,每次訪問對應的不同的 Action 對象。這個注解相當於在 spring 中保證了這一點。
有問題啊:為什么 spring mvc 又是建議單例的呢?它不擔心數據安全嗎? -- 個人理解:我們表現層使用 struts 時建議是多例的原因是,Struts 是通過模型驅動和屬性驅動來獲取前端頁面參數的,Action 里面存在大量成員變量,單例模式會導致屬性重復使用,數據不安全。而 spring mvc 獲取參數的模式是通過方法形參,一般之作用於方法,故不需要開啟多例。
6、@Autowired:默認按類型進行自動裝配。在容器查找匹配的Bean,當有且僅有一個匹配的Bean時,Spring將其注入@Autowired標注的變量中。
7、@Resource:默認按名稱裝配,當找不到與名稱匹配的bean才會按類型裝配。
AOP
-- Aspect-Oriented Programming 面向切面編程
前言:我們都知道 Java 是 OOP-面向對象編程的,它有自己的優勢,也有自己的不足。比如說:在我們開發中,都會有一條業務主線(即客戶的需求)。而我們要做的就是實現這個主線上的需求。我們在實現這些功能的時候,經常要干一些額外的不可避免的事情,比如事務的管理,日志的記錄等,就很繁雜且代碼量增多。
所以 Spring 提供了另一種角度來思考程序結構,也就是把這一些事情剝離出來,然后適時適地的把它們加入到我們的代碼中,比如說 聲明式事務管理的時候,我們在 service 層檢測到save*、update*這些方法要被調用的時候,我們先進行開啟事務什么的,這就是AOP,面向編程的思想。
總的來說,在運行時,動態地將代碼切入到類的指定方法、指定位置上的編程思想就是面向切面的編程。
AOP 名詞的大白話解說
1、通知 -- Advice
就是要給目標類織入的事情。就是我們說的額外的一些共同的事情,也就是上面說的 事務,日志等。你給先定義好,然后在想用的地方用一下。
2、連接點 -- JoinPoint
就是 spring 允許你使用通知的地方,那可真就多了,基本每個方法的前,后(兩者都有也行),或拋出異常時都可以是連接點,spring 的話只支持方法連接點。和方法有關的前前后后(拋出異常),都是連接點。一個類的所有方法前、后、拋出異常時等都是連接點。
3、切入點 -- Pointcut
上面說的連接點的基礎上,來定義切入點,你的一個類里,有15個方法,那就有幾十個連接點了對把,但是你並不想在所有方法附近都使用通知(使用叫織入,下面再說),你只想讓其中的幾個,在調用這幾個方法之前,之后或者拋出異常時干點什么,那么就用切點來定義這幾個方法,讓切點來篩選連接點,選中那幾個你想要的方法。(比如需要開啟事務的只是“ save * ”、“ update * ”..等等這些方法)。切入點就是定義了哪個類里面的哪些方法的會得到通知。
4、切面 -- Aspect
切面是通知和切入點的結合。現在發現了吧,沒連接點什么事情,連接點就是為了讓你好理解切點,搞出來的,明白這個概念就行了。通知說明了干什么和什么時候干(什么時候通過方法名中的before,after,around等就能知道),而切入點說明了在哪干(指定到底是哪個方法),這就是一個完整的切面定義。
5、織入 -- weaving
把切面應用到目標對象來創建新的代理對象的過程。可以在編譯時、類加載時、運行時完成的織入,spring 采用的是 在運行時完成織入。
6、引入 -- introduction
允許我們向現有的類添加新方法屬性。這不就是把切面(也就是新方法屬性:通知定義的)用到目標類中嗎~
7、目標 -- target
引入中所提到的目標類,也就是要被通知的對象,也就是真正的業務邏輯,他可以在毫不知情的情況下,被咱們織入切面。而自己專注於業務本身的邏輯。
8、AOP 的代理 -- AOP Proxy
目標對象被織入增強后產生的結果類。我的理解它是 spring 為了騙過 jvm 的類型檢查,搞出來的一個偽裝類。
spring 偽裝采用了兩種方式:
① 實現和目標類相同的接口 -- 與目標類為雙胞胎兄弟(要找我哥辦事,弟弟我冒充哥哥收點禮物,再讓我哥給你辦事~)
② 生成子類調用 -- 給目標類當兒子(學會了爸爸的本事,都找我辦就好了,但是我要先收點禮物~)
IOC
-- Inversion of Control 控制反轉
創建對象的控制權,被反轉到了 spring 框架。意味着將你設計好的對象交給 spring 控制管理,而不是傳統的在你的對象內部直接控制。
DI -- Dependency Injection 依賴注入
由 IOC 容器動態的將某個對象所需要的外部資源(包括對象、資源、常量數據)注入到組件( spring 中的組件如:controller, service..等)之中。
大白話:也就是 IOC 會把你當前對象所需要的外部資源動態的注入給你。
IOC 和 DI -- “被注入對象依賴IOC容器配置依賴對象”。
大白話:首先控制反轉,我們把對象的控制權交給了 spring 框架的 IOC 容器,所以我們要使用的話,就是依賴 IOC 容器給我們動態注入。
大白話解說IOC(控制反轉)和DI(依賴注入):
舉個栗子!在 UserAction 中要用到 UserServiceImpl 中的方法,最初的方法是在 UserAction 中通過 UserService userService = new UserServiceImpl; 需要它的時候就 new 出來,控制權在自己手里,但是使用 Spring 后,UserAction 不用主動去創建 UserServiceImpl 的實例了,這個工作已經交給 Spring來做了。然后 你要用的時候再直接問 Spring 要,就可以拿來用了。
這個時候你就由原來的主動創建,變成了被動依賴 Spring 創建好之后給你的注入,才能使用。控制權已經反轉給 Spring 了~