我的控制反转,依赖注入和面向切面编程的理解
生活随笔
收集整理的這篇文章主要介紹了
我的控制反转,依赖注入和面向切面编程的理解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
感謝http://blog.xiaohansong.com/2015/10/21/IoC-and-DI/ 的供圖
1.什么是控制? 如下圖所示,我們看到了 軟件系統中 對象的 高耦合現象。全體齒輪的轉動由一個對象來控制,如類B。
2.什么是 控制反轉? 是用來對對象進行解耦。借助第三方實現具有依賴關系的的對象之間的解耦。這個第三方就是 ioc 容器。引入了 ioc 容器后,對象 A、B、C、D 之間沒有了依賴關系,全體齒輪轉動的控制權交給 容器。這時候齒輪轉動控制權不屬于任何對象,而屬于ioc 容器,所以控制權反轉了,從 某個對象 轉到了 ioc 容器。
3. 什么是依賴注入? 3.1 什么是依賴?依賴就是指一種關系,如果 在類A中 創建了 類B的實例,我們說 類A 依賴 類B。 3.2 看個荔枝: public class class A{ B b; public A(){ b = new B(); } void func(){ b.func(); } } 出現的問題(problems):
4.依賴反轉 4.1 根據依賴注入的定義: 被依賴者對象并不是依賴者自己主動初始化,而是通過外部傳入被依賴者的方式,那么被依賴者對象類型 可以是 其 本身,也可以使其實現類或繼承子類; 4.2 所以,經過分析,被依賴者的對象類型 并不是 依賴者自身可以決定的,(當然傳統的程序設計方式是依賴者 決定的),而是由外部創建者決定的,所以 被依賴者類型的決定權反轉了。對于spirng來說 ,就是由 spring容器決定的;
4.3 依賴反轉定義:被依賴者的 對象類型 并不是由依賴者自身可以決定的,而是由 外部創建者決定的,外部傳入什么類型的對象 就是 什么類型的對象 , 依賴者對其一無所知;
======================================================================================= 【AOP】 轉自:http://docs.jboss.org/aop/1.0/aspect-framework/userguide/en/html/what.html 【1】What is it? 面向切面編程是什么? 1)切面定義:一個切面是通常指散布在方法,類,對象層次結構或甚至整個對象模型中的共同特征。 它是看起來和氣味的行為差不多,它應該有結構,但你不能用代碼在傳統的面向對象技術中表示這種結構。 2)切面荔枝:例如,度量(時間,用于度量運行某個代碼片需要花費多長時間)是一個常見切面。 要從應用程序生成有用的日志,您必須(通常自由地)在代碼中散布信息性消息。 然而,度量是你的類或對象模型真正不應該關注的東西。 畢竟,度量與您的實際應用無關:它不代表客戶或帳戶,并且不實現業務規則。 它只是正交。 3)橫切關注點定義:在AOP中,像度量這樣的特征稱為橫切關注點,因為它是一種“截斷”對象模型中多個點但仍然截然不同的行為。作為一種開發方法,AOP建議您抽象和封裝橫切關注點。 4)橫切關注點荔枝:例如,假設您想要向應用程序添加代碼以測量調用特定方法所需的時間。 在純Java中,代碼看起來像下面這樣。 public class BankAccountDAO {public void withdraw(double amount) {long startTime = System.currentTimeMillis();try {// Actual method body...}finally {long endTime = System.currentTimeMillis() - startTime;System.out.println("withdraw took: " + endTime);}} } 代碼分析)雖然這段代碼工作,這個方法有一些問題:
【2】在JBoss 切面編程中創建切面 1)簡而言之,所有AOP框架定義了兩個東西:一種實現橫切關注點的方法,以及一個編程語言或一組標簽 -以指定如何應用這些代碼片段。(一種是 定義橫切關注點的方法,二是指定該橫切關注點在何處使用) 2)讓我們來看看JBoss AOP,它的橫切關注點,以及如何在JBoss中實現一個度量方面。 在JBoss AOP中創建度量方面的第一步是將度量特性封裝在自己的Java類中。 清單二將清單One的BankAccountDAO.withdraw()方法中的try / finally塊提取為Metrics,這是一個JBoss AOP攔截器類的實現。 清單二:在JBoss AOP攔截器中實現度量 public class Metrics implements org.jboss.aop.Interceptor 03. public Object invoke(Invocation invocation) throws Throwable { 05. long startTime = System.currentTimeMillis(); 06. try { 08. return invocation.invokeNext(); 09. } 10. finally { 12. long endTime = System.currentTimeMillis() - startTime; 13. java.lang.reflect.Method m = ((MethodInvocation)invocation).method; 14. System.out.println("method " + m.toString() + " time: " + endTime + "ms"); 15. } 16. } 17. } 對以上代碼的分析:
我的總結(AOP) 1)切面的抽象型定義:切面是散布在 方法,類,對象層次結構或 整個對象模型中的共同特征;(是一組特征) 2)切面荔枝:如 我們要對某方法的執行時間進行統計,代碼如下: public class BankAccountDAO {public void withdraw(double amount) {long startTime = System.currentTimeMillis();try {// Actual method body...}finally {long endTime = System.currentTimeMillis() - startTime;System.out.println("withdraw took: " + endTime);}} } 其中 有關于統計時間的都是特征,它們的共性都是因為要統計時間而 添加到 方法中的代碼塊;那所以這些代碼塊就組成了 切面; 3)以上代碼塊出現了問題 問題1)代碼重用率低:必須手動將該 切面代碼添加到 要統計方法執行時間的方法中; 問題2)代碼膨脹和可讀性低:計時代碼真的不用你去關心,這些切面代碼只會讓你的代碼更加 膨脹和難讀,因為你必須在一個try / finally塊中包含時間, 但這個時間與我們 方法的執行沒有任何關系; 問題3)不利于代碼擴展(代碼耦合性高):如果要擴展此功能以包括方法或失敗計數,或者甚至將這些統計信息注冊到更復雜的報告機制,則必須再次修改許多不同的文件; 最后的最后:這種時間度量方法很難維護,擴展和擴展,因為它分散在整個代碼庫中; 4)aop 是干什么的? 4.1)intro:面向切面編程提供了一種封裝切面行為的方法。AOP提供了程序控制,以指定您希望在執行代碼的實際主體之前調用 時間統計方法 來執行執行時間度量。 4.2)所有AOP框架定義了兩個東西:一種實現橫切關注點的方法,以及一個編程語言或一組標簽 -以指定如何應用這些代碼片段。(一種是 定義橫切關注點的方法,二是指定該橫切關注點在何時何處使用)
5)如何定義aop中橫切關注點的方法 和 指定該橫切關注點的應用地點 5.1)定義橫切關注點:將切面代碼度量特性封裝在自己的Java類中 public class Metrics implements org.jboss.aop.Interceptorpublic Object invoke(Invocation invocation) throws Throwable {long startTime = System.currentTimeMillis();try {return invocation.invokeNext(); // 調用真正的實體方法}finally {long endTime = System.currentTimeMillis() - startTime;java.lang.reflect.Method m = ((MethodInvocation)invocation).method;System.out.println("method " + m.toString() + " time: " + endTime + "ms");}}} 5.2)橫切關注點在何時何地使用? 要應用一個切面,您定義何時執行切面代碼。 這些執行點被稱為切入點。切入點類似于是一個正則表達式。 正則表達式匹配字符串時,切入點表達式匹配應用程序中的事件/點。 看個 切入點的定義: @Before("execution(** concert.Performance.perform(..))")
1.什么是控制? 如下圖所示,我們看到了 軟件系統中 對象的 高耦合現象。全體齒輪的轉動由一個對象來控制,如類B。
2.什么是 控制反轉? 是用來對對象進行解耦。借助第三方實現具有依賴關系的的對象之間的解耦。這個第三方就是 ioc 容器。引入了 ioc 容器后,對象 A、B、C、D 之間沒有了依賴關系,全體齒輪轉動的控制權交給 容器。這時候齒輪轉動控制權不屬于任何對象,而屬于ioc 容器,所以控制權反轉了,從 某個對象 轉到了 ioc 容器。
3. 什么是依賴注入? 3.1 什么是依賴?依賴就是指一種關系,如果 在類A中 創建了 類B的實例,我們說 類A 依賴 類B。 3.2 看個荔枝: public class class A{ B b; public A(){ b = new B(); } void func(){ b.func(); } } 出現的問題(problems):
- 問題1:如果現在要改變 類 B 生成方式,如需要用new B(String name)初始化 B,需要修改 類A中的源代碼;
- 問題2:如果想測試不同 B 對象對 A 的影響很困難,因為 B 的初始化被寫死在了 A 的構造函數中;
- 問題3:如果要對類B的實例進行調試時,就必須在類A中對類B的實例進行測試,增加了測試難度和復雜度;因為當出現問題時,不知道 是 類A的問題 還是 類B的問題;
4.依賴反轉 4.1 根據依賴注入的定義: 被依賴者對象并不是依賴者自己主動初始化,而是通過外部傳入被依賴者的方式,那么被依賴者對象類型 可以是 其 本身,也可以使其實現類或繼承子類; 4.2 所以,經過分析,被依賴者的對象類型 并不是 依賴者自身可以決定的,(當然傳統的程序設計方式是依賴者 決定的),而是由外部創建者決定的,所以 被依賴者類型的決定權反轉了。對于spirng來說 ,就是由 spring容器決定的;
4.3 依賴反轉定義:被依賴者的 對象類型 并不是由依賴者自身可以決定的,而是由 外部創建者決定的,外部傳入什么類型的對象 就是 什么類型的對象 , 依賴者對其一無所知;
======================================================================================= 【AOP】 轉自:http://docs.jboss.org/aop/1.0/aspect-framework/userguide/en/html/what.html 【1】What is it? 面向切面編程是什么? 1)切面定義:一個切面是通常指散布在方法,類,對象層次結構或甚至整個對象模型中的共同特征。 它是看起來和氣味的行為差不多,它應該有結構,但你不能用代碼在傳統的面向對象技術中表示這種結構。 2)切面荔枝:例如,度量(時間,用于度量運行某個代碼片需要花費多長時間)是一個常見切面。 要從應用程序生成有用的日志,您必須(通常自由地)在代碼中散布信息性消息。 然而,度量是你的類或對象模型真正不應該關注的東西。 畢竟,度量與您的實際應用無關:它不代表客戶或帳戶,并且不實現業務規則。 它只是正交。 3)橫切關注點定義:在AOP中,像度量這樣的特征稱為橫切關注點,因為它是一種“截斷”對象模型中多個點但仍然截然不同的行為。作為一種開發方法,AOP建議您抽象和封裝橫切關注點。 4)橫切關注點荔枝:例如,假設您想要向應用程序添加代碼以測量調用特定方法所需的時間。 在純Java中,代碼看起來像下面這樣。 public class BankAccountDAO {public void withdraw(double amount) {long startTime = System.currentTimeMillis();try {// Actual method body...}finally {long endTime = System.currentTimeMillis() - startTime;System.out.println("withdraw took: " + endTime);}} } 代碼分析)雖然這段代碼工作,這個方法有一些問題:
- 打開和關閉指標是非常困難的,因為您必須手動將try> / finally塊中的代碼添加到要基準的每個方法或構造函數。
- 分析代碼真的不屬于你的應用程序代碼。 它使你的代碼膨脹和更難讀,因為你必須在一個try / finally塊中包含時間。
- 如果要擴展此功能以包括方法或失敗計數,或者甚至將這些統計信息注冊到更復雜的報告機制,則必須再次修改許多不同的文件。
【2】在JBoss 切面編程中創建切面 1)簡而言之,所有AOP框架定義了兩個東西:一種實現橫切關注點的方法,以及一個編程語言或一組標簽 -以指定如何應用這些代碼片段。(一種是 定義橫切關注點的方法,二是指定該橫切關注點在何處使用) 2)讓我們來看看JBoss AOP,它的橫切關注點,以及如何在JBoss中實現一個度量方面。 在JBoss AOP中創建度量方面的第一步是將度量特性封裝在自己的Java類中。 清單二將清單One的BankAccountDAO.withdraw()方法中的try / finally塊提取為Metrics,這是一個JBoss AOP攔截器類的實現。 清單二:在JBoss AOP攔截器中實現度量 public class Metrics implements org.jboss.aop.Interceptor 03. public Object invoke(Invocation invocation) throws Throwable { 05. long startTime = System.currentTimeMillis(); 06. try { 08. return invocation.invokeNext(); 09. } 10. finally { 12. long endTime = System.currentTimeMillis() - startTime; 13. java.lang.reflect.Method m = ((MethodInvocation)invocation).method; 14. System.out.println("method " + m.toString() + " time: " + endTime + "ms"); 15. } 16. } 17. } 對以上代碼的分析:
- 在JBoss AOP下,Metrics類包裝withdraw():當調用代碼調用withdraw()時,AOP框架將方法調用分解為其部分,并將這些部分封裝到一個調用對象中。 然后框架調用位于調用代碼和實際方法體之間的任何方面。
- 當AOP框架解析方法調用時,它在第3行調用Metric的invoke方法。第8行包裝并委托給實際的方法,并使用一個封閉的try / finally塊來執行定時。 第13行從調用對象獲取有關方法調用的上下文信息,而第14行顯示方法名稱和計算的度量。
- 將度量代碼放在其自己的對象中允許我們以后輕松擴展和捕獲額外的測量。現在,度量被封裝到一個方面,讓我們看看如何應用它。
我的總結(AOP) 1)切面的抽象型定義:切面是散布在 方法,類,對象層次結構或 整個對象模型中的共同特征;(是一組特征) 2)切面荔枝:如 我們要對某方法的執行時間進行統計,代碼如下: public class BankAccountDAO {public void withdraw(double amount) {long startTime = System.currentTimeMillis();try {// Actual method body...}finally {long endTime = System.currentTimeMillis() - startTime;System.out.println("withdraw took: " + endTime);}} } 其中 有關于統計時間的都是特征,它們的共性都是因為要統計時間而 添加到 方法中的代碼塊;那所以這些代碼塊就組成了 切面; 3)以上代碼塊出現了問題 問題1)代碼重用率低:必須手動將該 切面代碼添加到 要統計方法執行時間的方法中; 問題2)代碼膨脹和可讀性低:計時代碼真的不用你去關心,這些切面代碼只會讓你的代碼更加 膨脹和難讀,因為你必須在一個try / finally塊中包含時間, 但這個時間與我們 方法的執行沒有任何關系; 問題3)不利于代碼擴展(代碼耦合性高):如果要擴展此功能以包括方法或失敗計數,或者甚至將這些統計信息注冊到更復雜的報告機制,則必須再次修改許多不同的文件; 最后的最后:這種時間度量方法很難維護,擴展和擴展,因為它分散在整個代碼庫中; 4)aop 是干什么的? 4.1)intro:面向切面編程提供了一種封裝切面行為的方法。AOP提供了程序控制,以指定您希望在執行代碼的實際主體之前調用 時間統計方法 來執行執行時間度量。 4.2)所有AOP框架定義了兩個東西:一種實現橫切關注點的方法,以及一個編程語言或一組標簽 -以指定如何應用這些代碼片段。(一種是 定義橫切關注點的方法,二是指定該橫切關注點在何時何處使用)
5)如何定義aop中橫切關注點的方法 和 指定該橫切關注點的應用地點 5.1)定義橫切關注點:將切面代碼度量特性封裝在自己的Java類中 public class Metrics implements org.jboss.aop.Interceptorpublic Object invoke(Invocation invocation) throws Throwable {long startTime = System.currentTimeMillis();try {return invocation.invokeNext(); // 調用真正的實體方法}finally {long endTime = System.currentTimeMillis() - startTime;java.lang.reflect.Method m = ((MethodInvocation)invocation).method;System.out.println("method " + m.toString() + " time: " + endTime + "ms");}}} 5.2)橫切關注點在何時何地使用? 要應用一個切面,您定義何時執行切面代碼。 這些執行點被稱為切入點。切入點類似于是一個正則表達式。 正則表達式匹配字符串時,切入點表達式匹配應用程序中的事件/點。 看個 切入點的定義: @Before("execution(** concert.Performance.perform(..))")
總結
以上是生活随笔為你收集整理的我的控制反转,依赖注入和面向切面编程的理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 程序的初始化顺序是怎样的?
- 下一篇: ReviewForJob——java虚拟