偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

IoC容器總結(jié)與簡單模擬

開發(fā) 后端
當(dāng)一個組件需要外部資源時,最直接也最明智的方法是執(zhí)行查找,這種行為稱為主動查找。但這種查找存在一個缺點——組件需要知道如何獲得資源。那么它的解決方案是什么呢?請看下文。

當(dāng)一個組件需要外部資源時,最直接也最明智的方法是執(zhí)行查找,這種行為稱為主動查找。但這種查找存在一個缺點——組件需要知道如何獲得資源。一個好的獲取資源的解決方案是應(yīng)用IoC(Inversion of Control,控制反轉(zhuǎn))。它的思想是反轉(zhuǎn)資源獲取的方向。傳統(tǒng)的資源查找方式是要求組件向容器發(fā)起請求來查找資源,作為回應(yīng),容器適時的返回資源。而應(yīng)用了IoC之后,則是容器主動的將資源推送到它所管理的組件里,組件所要做的僅僅是選擇一種合適的方式接受資源。

IoC是一種通用的設(shè)計原則,而DI(Dependency Injection,依賴注入)則是具體的設(shè)計模式,它體現(xiàn)了IoC的設(shè)計原則。DI是IoC典型的實現(xiàn),所以IoC與DI術(shù)語會被混用。IoC與DI的關(guān)系就好比Java中的"接口"和"接口的實現(xiàn)類"的關(guān)系一樣。

在DI模式下,容器全權(quán)負(fù)責(zé)的組件的裝配,容器以一些預(yù)先定義好的方式(例如setter方法或構(gòu)造函數(shù))將匹配的資源注入到每個組件里。目前有三種類型的DI:

setter注入,setter注入會存在一些問題,1. 容易出現(xiàn)忘記調(diào)用setter方法注入組件所需要的依賴,將會導(dǎo)致NullPointerException異常。2. 代碼會存在安全問題,第一次注入后,不能阻止再次調(diào)用setter,除非添加額外的處理工作。但是由于setter注入非常簡單所以非常流行(絕大多數(shù)Java IDE都支持自動生成setter方法)。
構(gòu)造器注入,構(gòu)造器注入能夠一定程度上解決setter注入的問題。但是該中注入方式也會帶來一些問題,如果組件有很多的依賴,則構(gòu)造函數(shù)的參數(shù)列表將變得冗長,會降低代碼可讀性。
接口注入 ,該注入方式使用的非常少,它要求組件必須實現(xiàn)某個接口,容器正是通過這個接口實現(xiàn)注入依賴的。接口注入的缺點比較明顯,使用接口注入需要實現(xiàn)特定的接口,而接口又特定于容器,所以組件對容器產(chǎn)生了依賴,一旦脫離容器,組件不能重用。這是一種"侵入式"注入。

其中"setter注入"和"構(gòu)造器注入"是被廣泛運用的,絕大多數(shù)的IoC容器都支持這兩種DI類型。

模仿Spring IoC容器

假設(shè)一個系統(tǒng)的功能之一是能夠生成PDF或HTML格式的報表。

  1. /*生成報表的通用接口*/ 
  2. public interface ReportBuilder  
  3. {  
  4.     public void build(String data);  

生成PDF和HTML格式的實現(xiàn)類:

  1. /*生成HTML格式報表*/ 
  2. public class ReportHtmlBuilder implements ReportBuilder {  
  3.     @Override 
  4.     public void build(String data) {  
  5.         /*示意代碼*/ 
  6.         System.out.println("build html report!");  
  7.     }  
  8. }  
  9.  
  10. /*生成PDF格式報表*/ 
  11. public class ReportPdfBuilder implements ReportBuilder {  
  12.     @Override 
  13.     public void build(String data) {  
  14.         System.out.println("build pdf report!");  
  15.     }  

報表服務(wù)類:

  1. /*報表服務(wù)類*/ 
  2. public class ReportService   
  3. {  
  4.     /*依賴"ReportBuilder"*/ 
  5.     private ReportBuilder builder;  
  6.       
  7.     public ReportBuilder getBuilder()  
  8.     {  
  9.         return builder;  
  10.     }  
  11.       
  12.     /*setter注入*/ 
  13.     public void setBuilder(ReportBuilder builder)  
  14.     {  
  15.         this.builder = builder;  
  16.     }  
  17.  
  18.     public void builderYearReport(int year)  
  19.     {  
  20.         this.builder.build("data");  
  21.     }  

IoC容器配置文件"component.properties"

  1. pdfBuilder=com.beliefbitrayal.ioc.inter.imp.ReportPdfBuilder  
  2. htmlBuilder=com.beliefbitrayal.ioc.inter.imp.ReportHtmlBuilder  
  3. reportService=com.beliefbitrayal.ioc.server.ReportService  
  4. reportService.builder=htmlBuilder 

IoC容器:

  1. public class Container  
  2. {  
  3.     /*用于儲存Component的容器*/ 
  4.     private Map<String, Object> repository = new HashMap<String, Object>();  
  5.  
  6.     public Container()  
  7.     {  
  8.         try 
  9.         {  
  10.             /*讀取容器配置文件"component.properties"*/ 
  11.             Properties properties = new Properties();  
  12.             properties.load(new FileInputStream("src/component.properties"));  
  13.               
  14.             /*獲取配置文件的每一行信息*/ 
  15.             for(Map.Entry<Object, Object> entry : properties.entrySet())  
  16.             {  
  17.                 String key = (String)entry.getKey();  
  18.                 String value = (String)entry.getValue();  
  19.                   
  20.                 /*處理配置文件的每一行信息*/ 
  21.                 this.handler(key, value);  
  22.             }  
  23.         }  
  24.         catch (Exception e)  
  25.         {  
  26.             e.printStackTrace();  
  27.         }  
  28.     }  
  29.       
  30.     private void handler(String key,String value) throws Exception  
  31.     {  
  32.         /*  
  33.          * reportService=com.beliefbitrayal.ioc.server.ReportService  
  34.          * reportService.builder=htmlBuilder  
  35.          * 第一種情況,key值中間沒有"."說明為一個新組件。對它的處理為創(chuàng)建它的對象,將其對象放入Map中。  
  36.          * 第二種情況,key值中間出現(xiàn)"."說明這個屬性條目是一個依賴注入。根據(jù)"."的位置將這個key值劃分為兩部分,第一部分為組件的名字,第二部分為  
  37.          * 該組件需要設(shè)置的屬性。  
  38.          */ 
  39.         String[] parts = key.split("\\.");  
  40.           
  41.         /*情況1*/ 
  42.         if(parts.length == 1)  
  43.         {  
  44.             /*通過反射的方式創(chuàng)建組件的對象*/ 
  45.             Object object = Class.forName(value).newInstance();  
  46.               
  47.             this.repository.put(key, object);  
  48.         }  
  49.         else 
  50.         {  
  51.             /*對于情況2,首先用key值的第一部分(組件名)獲取組件*/ 
  52.             Object object = this.repository.get(parts[0]);  
  53.               
  54.             /*再使用value值指定的組件名從Map對象中獲取依賴*/ 
  55.             Object reference = this.repository.get(value);  
  56.               
  57.             /*將獲取的依賴注入到指定的組件的相應(yīng)屬性上,"PropertyUtils"類屬于Apache下Commons BeanUtil第三方類庫,  
  58.              * 要使用它還需要下載Commons Logging第三方類庫  
  59.              */ 
  60.             PropertyUtils.setProperty(object, parts[1], reference);  
  61.         }  
  62.     }  
  63.  
  64.     public Object getComponent(String key)  
  65.     {  
  66.         return this.repository.get(key);  
  67.     }  

根據(jù)配置文件,我們在場景類中使用的報表應(yīng)該是HTML格式的:

  1. public class Client  
  2. {  
  3.     public static void main(String[] args)  
  4.     {  
  5.         /*創(chuàng)建容器*/ 
  6.         Container container = new Container();  
  7.           
  8.         /*從容器中獲取"報表服務(wù)類"*/ 
  9.         ReportService reportService = (ReportService)container.getComponent("reportService");  
  10.           
  11.         /*顯示報表*/ 
  12.         reportService.builderYearReport(0);  
  13.     }  

控制臺的輸出:

  1. build html report! 

我們?nèi)粜枰狿DF格式的只需要修改屬性文件即可:

  1. pdfBuilder=com.beliefbitrayal.ioc.inter.imp.ReportPdfBuilder  
  2. htmlBuilder=com.beliefbitrayal.ioc.inter.imp.ReportHtmlBuilder  
  3. reportService=com.beliefbitrayal.ioc.server.ReportService  
  4. reportService.builder=pdfBuilder 

場景類不變,控制臺輸出:

  1. build pdf report! 

容器可以從基于文本的控制文件中讀取組件的定義,這使得容器可以重用?,F(xiàn)在即使隨意改變組件的定義,都不用修改容器的代碼。這個例子很好的演示了IoC容器的核心原理和機制。

通過以上分析和舉例,控制反轉(zhuǎn)IoC就是一個組件的依賴是由容器來裝配,組件不做定位查詢,只提供普通的Java方法讓容器去裝配依賴關(guān)系,IoC容器是一般通過setter注入或構(gòu)造函數(shù)注入的方式將依賴注入到組件中的,組件的依賴我們一般通過一個配置文件來描述(XML或Properties),配置文件在IoC容器被構(gòu)建時讀取解析。

原文鏈接:http://www.cnblogs.com/beliefbetrayal/archive/2012/02/02/2335192.html

【編輯推薦】

  1. Java編程語言的認(rèn)識誤區(qū)
  2. Java Thread的概述與總結(jié)
  3. Java路線圖:甲骨文的兩年計劃
  4. Java 8將支持無符號整型
  5. 深入研究Java虛擬機的類加載機制
責(zé)任編輯:林師授 來源: 信仰や欺騙的博客
相關(guān)推薦

2009-04-21 11:27:52

MVCJSPJDBC

2018-01-15 14:36:34

Linux負(fù)載CPU

2009-06-22 10:20:01

Spring IoC容

2020-08-17 07:59:47

IoC DINestJS

2013-07-05 14:47:51

IoC需求

2023-08-09 18:26:02

光纖綜合布線

2021-02-06 13:28:21

鴻蒙HarmonyOS應(yīng)用開發(fā)

2023-08-16 17:44:38

2021-01-14 18:17:33

SpringFrameIOCJava

2018-03-13 12:46:41

單模多模光纖

2025-06-10 10:15:00

Java容器并發(fā)

2010-07-21 15:30:40

SQL Server

2023-03-20 13:41:00

IoC容器Spring

2025-03-14 10:37:24

SpringSpring IOC容器

2025-05-21 10:09:09

Spring 5.xIOC編程

2023-08-29 15:45:20

單模光纖多模光纖

2022-12-27 08:12:27

IOC容器Bean

2017-09-22 10:53:52

HTTPHTTP2TCP協(xié)議

2011-06-27 13:17:07

Java EE

2013-01-18 09:59:35

SQL Server
點贊
收藏

51CTO技術(shù)棧公眾號