日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

我的控制反转,依赖注入和面向切面编程的理解

發(fā)布時間:2023/12/3 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 我的控制反转,依赖注入和面向切面编程的理解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
感謝http://blog.xiaohansong.com/2015/10/21/IoC-and-DI/ 的供圖

1.什么是控制? 如下圖所示,我們看到了 軟件系統(tǒng)中 對象的 高耦合現(xiàn)象。全體齒輪的轉動由一個對象來控制,如類B。


2.什么是 控制反轉? 是用來對對象進行解耦借助第三方實現(xiàn)具有依賴關系的的對象之間的解耦。這個第三方就是 ioc 容器。引入了 ioc 容器后,對象 A、B、C、D 之間沒有了依賴關系全體齒輪轉動的控制權交給 容器。這時候齒輪轉動控制權不屬于任何對象,而屬于ioc 容器,所以控制權反轉了,從 某個對象 轉到了 ioc 容器。

3. 什么是依賴注入? 3.1 什么是依賴?依賴就是指一種關系,如果 在類A中 創(chuàng)建了 類B的實例,我們說 類A 依賴 類B。 3.2 看個荔枝: public class class A{ B b; public A(){ b = new B(); } void func(){ b.func(); } } 出現(xiàn)的問題(problems):
  • 問題1:如果現(xiàn)在要改變 類 B 生成方式,如需要用new B(String name)初始化 B,需要修改 類A中的源代碼;
  • 問題2:如果想測試不同 B 對象對 A 的影響很困難,因為 B 的初始化被寫死在了 A 的構造函數(shù)中
  • 問題3:如果要對類B的實例進行調(diào)試時,就必須在類A中對類B的實例進行測試,增加了測試難度和復雜度;因為當出現(xiàn)問題時,不知道 是 類A的問題 還是 類B的問題;
解決方法: public class class A{ B b; public A(B b){ this.b = b; } void func(){ b.func(); } } 3.3)依賴注入定義: 將B對象實例 作為類A的構造器參數(shù)進行傳入,在調(diào)用類A 構造器之前,類B實例已經(jīng)被初始化好了。像這種非自己主動初始化依賴,而通過外部傳入依賴對象的方式,我們就稱為依賴注入
4.依賴反轉 4.1 根據(jù)依賴注入的定義: 被依賴者對象并不是依賴者自己主動初始化,而是通過外部傳入被依賴者的方式,那么被依賴者對象類型 可以是 其 本身,也可以使其實現(xiàn)類或繼承子類; 4.2 所以,經(jīng)過分析,被依賴者的對象類型 并不是 依賴者自身可以決定的,(當然傳統(tǒng)的程序設計方式是依賴者 決定的),而是由外部創(chuàng)建者決定的,所以 被依賴者類型的決定權反轉了。對于spirng來說 ,就是由 spring容器決定的;
4.3 依賴反轉定義:被依賴者的 對象類型 并不是由依賴者自身可以決定的,而是由 外部創(chuàng)建者決定的,外部傳入什么類型的對象 就是 什么類型的對象 , 依賴者對其一無所知;
======================================================================================= 【AOP 轉自:http://docs.jboss.org/aop/1.0/aspect-framework/userguide/en/html/what.html 【1】What is it? 面向切面編程是什么? 1)切面定義:一個切面是通常指散布在方法,類,對象層次結構或甚至整個對象模型中的共同特征。 它是看起來和氣味的行為差不多,它應該有結構,但你不能用代碼在傳統(tǒng)的面向?qū)ο蠹夹g中表示這種結構。 2)切面荔枝:例如,度量(時間,用于度量運行某個代碼片需要花費多長時間)是一個常見切面。 要從應用程序生成有用的日志,您必須(通常自由地)在代碼中散布信息性消息。 然而,度量是你的類或?qū)ο竽P驼嬲粦撽P注的東西。 畢竟,度量與您的實際應用無關:它不代表客戶或帳戶,并且不實現(xiàn)業(yè)務規(guī)則。 它只是正交。 3)橫切關注點定義:在AOP中,像度量這樣的特征稱為橫切關注點,因為它是一種“截斷”對象模型中多個點但仍然截然不同的行為。作為一種開發(fā)方法,AOP建議您抽象和封裝橫切關注點。 4)橫切關注點荔枝:例如,假設您想要向應用程序添加代碼以測量調(diào)用特定方法所需的時間。 在純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塊中的代碼添加到要基準的每個方法或構造函數(shù)。
  • 分析代碼真的不屬于你的應用程序代碼。 它使你的代碼膨脹和更難讀,因為你必須在一個try / finally塊中包含時間。
  • 如果要擴展此功能以包括方法或失敗計數(shù),或者甚至將這些統(tǒng)計信息注冊到更復雜的報告機制,則必須再次修改許多不同的文件。
這種度量方法很難維護,擴展和擴展,因為它分散在整個代碼庫中。 這只是一個很小的例子! 在許多情況下,OOP可能不總是向類添加指標的最佳方法。 面向方面的編程提供了一種封裝這種類型的行為功能的方法。 它允許您添加行為,如度量“圍繞”您的代碼。 例如,AOP為您提供了程序控制,以指定您希望在執(zhí)行代碼的實際主體之前調(diào)用BankAccountDAO來執(zhí)行度量方面。
【2】在JBoss 切面編程中創(chuàng)建切面 1)簡而言之,所有AOP框架定義了兩個東西:一種實現(xiàn)橫切關注點的方法,以及一個編程語言或一組標簽 -以指定如何應用這些代碼片段。(一種是 定義橫切關注點的方法,二是指定該橫切關注點在何處使用) 2)讓我們來看看JBoss AOP,它的橫切關注點,以及如何在JBoss中實現(xiàn)一個度量方面。 在JBoss AOP中創(chuàng)建度量方面的第一步是將度量特性封裝在自己的Java類中。 清單二將清單One的BankAccountDAO.withdraw()方法中的try / finally塊提取為Metrics,這是一個JBoss AOP攔截器類的實現(xiàn)。 清單二:在JBoss AOP攔截器中實現(xiàn)度量 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():當調(diào)用代碼調(diào)用withdraw()時,AOP框架將方法調(diào)用分解為其部分,并將這些部分封裝到一個調(diào)用對象中。 然后框架調(diào)用位于調(diào)用代碼和實際方法體之間的任何方面。
  • 當AOP框架解析方法調(diào)用時,它在第3行調(diào)用Metric的invoke方法。第8行包裝并委托給實際的方法,并使用一個封閉的try / finally塊來執(zhí)行定時。 第13行從調(diào)用對象獲取有關方法調(diào)用的上下文信息,而第14行顯示方法名稱和計算的度量。
  • 將度量代碼放在其自己的對象中允許我們以后輕松擴展和捕獲額外的測量。現(xiàn)在,度量被封裝到一個方面,讓我們看看如何應用它。
【3】JBoss AOP中切面的應用 要應用一個方面,您定義何時執(zhí)行方面代碼。 這些執(zhí)行點被稱為切入點。 類似于切入點是一個正則表達式。 正則表達式匹配字符串時,切入點表達式匹配應用程序中的事件/點。 例如,有效的切入點定義將是“對于JDBC方法executeQuery()的所有調(diào)用,調(diào)用驗證SQL語法的方面”。
我的總結(AOP) 1)切面的抽象型定義:切面是散布在 方法,類,對象層次結構或 整個對象模型中的共同特征;(是一組特征) 2)切面荔枝:如 我們要對某方法的執(zhí)行時間進行統(tǒng)計,代碼如下: 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);}} } 其中 有關于統(tǒng)計時間的都是特征,它們的共性都是因為要統(tǒng)計時間而 添加到 方法中的代碼塊;那所以這些代碼塊就組成了 切面; 3)以上代碼塊出現(xiàn)了問題 問題1)代碼重用率低:必須手動將該 切面代碼添加到 要統(tǒng)計方法執(zhí)行時間的方法中; 問題2)代碼膨脹和可讀性低:計時代碼真的不用你去關心,這些切面代碼只會讓你的代碼更加 膨脹和難讀,因為你必須在一個try / finally塊中包含時間, 但這個時間與我們 方法的執(zhí)行沒有任何關系; 問題3)不利于代碼擴展(代碼耦合性高):如果要擴展此功能以包括方法或失敗計數(shù),或者甚至將這些統(tǒng)計信息注冊到更復雜的報告機制,則必須再次修改許多不同的文件; 最后的最后:這種時間度量方法很難維護,擴展和擴展,因為它分散在整個代碼庫中; 4)aop 是干什么的? 4.1)intro:面向切面編程提供了一種封裝切面行為的方法。AOP提供了程序控制,以指定您希望在執(zhí)行代碼的實際主體之前調(diào)用 時間統(tǒng)計方法 來執(zhí)行執(zhí)行時間度量。 4.2)所有AOP框架定義了兩個東西:一種實現(xiàn)橫切關注點的方法,以及一個編程語言或一組標簽 -以指定如何應用這些代碼片段。(一種是 定義橫切關注點的方法,二是指定該橫切關注點在何時何處使用)
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(); // 調(diào)用真正的實體方法}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)橫切關注點在何時何地使用? 要應用一個切面,您定義何時執(zhí)行切面代碼。 這些執(zhí)行點被稱為切入點。切入點類似于是一個正則表達式。 正則表達式匹配字符串時,切入點表達式匹配應用程序中的事件/點。 看個 切入點的定義: @Before("execution(** concert.Performance.perform(..))")

總結

以上是生活随笔為你收集整理的我的控制反转,依赖注入和面向切面编程的理解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。