成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

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

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

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

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

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

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

模仿Spring IoC容器

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

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

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

  1. /*生成HTML格式報(bào)表*/ 
  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格式報(bào)表*/ 
  11. public class ReportPdfBuilder implements ReportBuilder {  
  12.     @Override 
  13.     public void build(String data) {  
  14.         System.out.println("build pdf report!");  
  15.     }  

報(bào)表服務(wù)類:

  1. /*報(bào)表服務(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.     /*用于儲(chǔ)存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值中間沒(méi)有"."說(shuō)明為一個(gè)新組件。對(duì)它的處理為創(chuàng)建它的對(duì)象,將其對(duì)象放入Map中。  
  36.          * 第二種情況,key值中間出現(xiàn)"."說(shuō)明這個(gè)屬性條目是一個(gè)依賴注入。根據(jù)"."的位置將這個(gè)key值劃分為兩部分,第一部分為組件的名字,第二部分為  
  37.          * 該組件需要設(shè)置的屬性。  
  38.          */ 
  39.         String[] parts = key.split("\\.");  
  40.           
  41.         /*情況1*/ 
  42.         if(parts.length == 1)  
  43.         {  
  44.             /*通過(guò)反射的方式創(chuàng)建組件的對(duì)象*/ 
  45.             Object object = Class.forName(value).newInstance();  
  46.               
  47.             this.repository.put(key, object);  
  48.         }  
  49.         else 
  50.         {  
  51.             /*對(duì)于情況2,首先用key值的第一部分(組件名)獲取組件*/ 
  52.             Object object = this.repository.get(parts[0]);  
  53.               
  54.             /*再使用value值指定的組件名從Map對(duì)象中獲取依賴*/ 
  55.             Object reference = this.repository.get(value);  
  56.               
  57.             /*將獲取的依賴注入到指定的組件的相應(yīng)屬性上,"PropertyUtils"類屬于Apache下Commons BeanUtil第三方類庫(kù),  
  58.              * 要使用它還需要下載Commons Logging第三方類庫(kù)  
  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ù)配置文件,我們?cè)趫?chǎng)景類中使用的報(bào)表應(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.         /*從容器中獲取"報(bào)表服務(wù)類"*/ 
  9.         ReportService reportService = (ReportService)container.getComponent("reportService");  
  10.           
  11.         /*顯示報(bào)表*/ 
  12.         reportService.builderYearReport(0);  
  13.     }  

控制臺(tái)的輸出:

  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 

場(chǎng)景類不變,控制臺(tái)輸出:

  1. build pdf report! 

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

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

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

【編輯推薦】

  1. Java編程語(yǔ)言的認(rèn)識(shí)誤區(qū)
  2. Java Thread的概述與總結(jié)
  3. Java路線圖:甲骨文的兩年計(jì)劃
  4. Java 8將支持無(wú)符號(hào)整型
  5. 深入研究Java虛擬機(jī)的類加載機(jī)制
責(zé)任編輯:林師授 來(lái)源: 信仰や欺騙的博客
相關(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容

2013-07-05 14:47:51

IoC需求

2020-08-17 07:59:47

IoC DINestJS

2023-08-09 18:26:02

光纖綜合布線

2018-03-13 12:46:41

單模多模光纖

2021-02-06 13:28:21

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

2021-01-14 18:17:33

SpringFrameIOCJava

2010-07-21 15:30:40

SQL Server

2023-08-16 17:44:38

2025-06-10 10:15:00

Java容器并發(fā)

2025-03-14 10:37:24

SpringSpring IOC容器

2025-05-21 10:09:09

Spring 5.xIOC編程

2023-03-20 13:41:00

IoC容器Spring

2023-08-29 15:45:20

單模光纖多模光纖

2017-09-22 10:53:52

HTTPHTTP2TCP協(xié)議

2022-12-27 08:12:27

IOC容器Bean

2011-06-27 13:17:07

Java EE

2018-01-18 23:10:32

單模光纖多模光纖光纖
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 亚洲精品1| 精品国产乱码久久久久久88av | 天天插天天狠天天透 | 国产综合欧美 | 久久久久久免费毛片精品 | 日韩在线播放中文字幕 | 久久午夜精品福利一区二区 | 久久综合九色综合欧美狠狠 | 亚洲精品久久久蜜桃 | 三级黄色网址 | 中文字幕 在线观看 | 日本字幕在线观看 | 国产精品欧美一区二区 | 成人在线免费观看 | a级免费视频 | 91在线看| 中文二区 | 日韩av第一页| 久久99蜜桃综合影院免费观看 | 国内毛片毛片毛片毛片 | 99久久久久久 | 日韩午夜精品 | 超碰免费在线 | aaa精品 | 91亚洲国产成人久久精品网站 | 理伦毛片 | 天天色天天色 | 日韩在线视频一区 | 精品久久中文字幕 | 午夜一区二区三区视频 | 自拍视频一区二区三区 | 国产一区二区久久 | 中文字幕一区二区三区四区五区 | 懂色中文一区二区在线播放 | 国产精品久久国产愉拍 | 亚洲视频在线观看 | 男人天堂免费在线 | 欧美日韩综合 | 国产精品我不卡 | 欧美一区免费 | 爱草在线 |