企業級應用框架(五)IOC容器在框架中的應用

前言

  在上一篇我大致的介紹了這個系列所涉及到的知識點,在本篇我打算把IOC這一塊單獨提取出來講,因為IOC容器在解除框架層與層之間的耦合有著不可磨滅的作用。當然在本系列前面的三篇中我也提供了一種基于反射的解耦方式,但是始終不是很優雅,運用到項目中顯得別扭。目前,我所掌握的IOC容器主要有兩個:一個是 unity,另一個則是spring.net,經過慎重的思考我還是決定選擇unity 2.0做為本系列的IOC容器,原因主要有兩個:第一,他是一個輕量級的容器且師出名門(微軟),第二,它提供了簡單的攔截機制,在它的基礎上實現AOP顯得非常的簡單,下面開始我們今天的議題......

什么是IOC容器

  IOC容器是對控制反轉與依賴注入的一種實現,關于什么是控制反轉,什么是依賴注入,網上一搜一大把,我這里就不在多說了,我們需要關注的就是IOC容器到底能夠為我們做些什么事情,其實說白了,IOC容器就是通過相應的配置,用來為我們創建實例,使我們擺脫了new的魔咒,這在層與層之間的解耦中有著重要的意義,至于層次間為什么要解耦請參見我的第一篇, 本文著重介紹unity 2.0,您需要在項目中添加對Microsoft.Practices.Unity.dll與Microsoft.Practices.Unity.Configuration.dll的引用,下面我通過簡單doom來講述它的運用,程序如圖

IOC項目引用了IService項目,但并未引用service項目,IService項目中定義的是服務接口,Service項目引用了IService項目并實現了里面的服務接口。我們現在要做的事情就是在IOC中采用IService接口標識服務,在調用時采用unity容器讀取配置文件幫助我們把接口實例化,其具體的服務來自Service項目(我們的IOC項目沒有引用Service項目所以是無法new的),為了很好的運用Unity容器,我做了一下封裝,代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System.Configuration;
using System.Reflection;namespace IOC
{public class ServiceLocator{/// <summary>/// IOC容器/// </summary>private readonly IUnityContainer container;private static readonly ServiceLocator instance = new ServiceLocator();/// <summary>/// 服務定位器單例/// </summary>public static ServiceLocator Instance{get { return instance; }}private ServiceLocator(){//讀取容器配置文件UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");//創建容器container = new UnityContainer();//配置容器
            section.Configure(container);}#region   /// <summary>/// 創建構造函數參數/// </summary>/// <param name="overridedArguments"></param>/// <returns></returns>private IEnumerable<ParameterOverride> GetParameterOverrides(object overridedArguments){List<ParameterOverride> overrides = new List<ParameterOverride>();Type argumentsType = overridedArguments.GetType();argumentsType.GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList().ForEach(property =>{var propertyValue = property.GetValue(overridedArguments, null);var propertyName = property.Name;overrides.Add(new ParameterOverride(propertyName, propertyValue));});return overrides;}#endregion#region 公共方法/// <summary>/// 創建指定類型的容器/// </summary>/// <typeparam name="T"></typeparam>/// <returns></returns>public T GetService<T>(){return container.Resolve<T>();}/// <summary>/// 根據指定名稱的注冊類型/// 創建指定的類型/// </summary>/// <typeparam name="T"></typeparam>/// <param name="name">注冊類型配置節點名稱</param>/// <returns></returns>public T GetService<T>(string name){return container.Resolve<T>(name);}/// <summary>/// 用指定的構造函數參數/// 創建實體/// </summary>/// <typeparam name="T">實體類型</typeparam>/// <param name="overridedArguments">屬性名對應參數名,屬性值對應/// 參數值得動態參數實體</param>/// <returns></returns>public T GetService<T>(object overridedArguments){var overrides = GetParameterOverrides(overridedArguments);return container.Resolve<T>(overrides.ToArray());}/// <summary>/// /// </summary>/// <typeparam name="T"></typeparam>/// <param name="name"></param>/// <param name="overridedArguments"></param>/// <returns></returns>public T GetService<T>(string name,object overridedArguments){var overrides = GetParameterOverrides(overridedArguments);return container.Resolve<T>(name, overrides.ToArray());}#endregion}
}
View Code

好了,下面開始我們的測試,我們首先在IService項目創建一個ISayHello服務接口代碼如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace IService
{public interface ISayHello{string hello();}
}
View Code

下面我們在Service項目中創建一個ChineseSayHello服務實現ISayHello接口代碼如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IService;namespace Service
{public class ChineseSayHello : ISayHello{public string hello(){return "你好";}}
}
View Code

下面我們創建一個測試頁面Test.aspx,后臺代碼如下

using IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;namespace IOC
{public partial class Test : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){ISayHello sayhello = ServiceLocator.Instance.GetService<ISayHello>();showInfo.InnerText = sayhello.hello();}}
}
View Code

好,下面來看一看我們的配置文件

<?xml version="1.0" encoding="utf-8"?><!--有關如何配置 ASP.NET 應用程序的詳細消息,請訪問http://go.microsoft.com/fwlink/?LinkId=169433-->
<configuration><configSections><section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/></configSections><unity xmlns="http://schemas.microsoft.com/practices/2010/unity"><container><register  type="IService.ISayHello,IService"  mapTo="Service.ChineseSayHello,Service"></register></container></unity><system.web><compilation debug="true" targetFramework="4.0" /></system.web>
</configuration>

<register/>節點是告訴容器我要向容器中注冊一個ISayHello接口類型,并且當每次要創建的ISayHello類型的時候都映射到ChineseSayHello實例。我們執行程序,得到的結果為:你好,這說明我們的容器正確的為我們創建ChineseSayHello實例。如果有一天我們覺得ChineseSayHello不好,我們想換一個服務來實現ISayHello,比如:EnglishSayHello,從而替代ChineseSayHello,我們僅需要創建一個EnglishSayHello類型,修改下配置文件,如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IService;namespace Service
{public class EnglishSayHello : ISayHello{public string hello(){return "hello";}}
}
View Code
<?xml version="1.0" encoding="utf-8"?><!--有關如何配置 ASP.NET 應用程序的詳細消息,請訪問http://go.microsoft.com/fwlink/?LinkId=169433-->
<configuration><configSections><section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/></configSections><unity xmlns="http://schemas.microsoft.com/practices/2010/unity"><container><!--<register  type="IService.ISayHello,IService"  mapTo="Service.ChineseSayHello,Service"></register>--><register  type="IService.ISayHello,IService"  mapTo="Service.EnglishSayHello,Service"></register></container></unity><system.web><compilation debug="true" targetFramework="4.0" /></system.web>
</configuration>
View Code

程序的運行結果為:hello,實例創建成功。簡簡單單的一個例證,我們看見了IOC容器在給我們帶來的巨大好處,我們IOC層根本不再依賴于具體的服務,我們想要什么實例配置下文件即可,這樣極大的增加了程序的靈活性與可擴張性.

????下面,我們來討論一下容器實例的生命周期,也就是實例在容器中的存活時間。舉個例子,我們在同樣的配置文件下連續創建多個ISayHello服務實例,很顯然,這樣的多個實例是來自同樣的類型的,現在我們關心的是容器是每一次都會為我們創建該類型的實例,還是僅僅只為我們創建一個,以后所有的ISayHello都引用同一個實例呢?我們測試下,代碼如下

using IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;namespace IOC
{public partial class Test : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){ISayHello sayhello = ServiceLocator.Instance.GetService<ISayHello>();ISayHello sayhello1 = ServiceLocator.Instance.GetService<ISayHello>();showInfo.InnerText = sayhello.GetHashCode().Equals(sayhello1.GetHashCode()).ToString();}}
}
View Code

我們得到的結果是False,很顯然容器每次都為我們去創建了一個實例。事實上Unity容器創建實例的機制是這樣的:首先去容器中查找有沒有這樣的實例還保持在容器中,如果有的話則直接拿出來,如果沒有的話則重新去創建一個。現在關鍵的問題是容器采用什么用的機制去保存這些被創建出來的實例,也就是實例在容器中的生命周期,在默認的情況下,實例被創建出來,容器即不再保存該實例,故在下次創建的時候容器找不到這樣的實例,從而重新創建該類型實例,事實上實例的生命周期是可以配置的,我們甚至可以自定義實例的生命周期,下面我們修改下配置文件,設置實例的lifetime類型為singleton,即讓實例永遠保持在容器中,如下

<?xml version="1.0" encoding="utf-8"?><!--有關如何配置 ASP.NET 應用程序的詳細消息,請訪問http://go.microsoft.com/fwlink/?LinkId=169433-->
<configuration><configSections><section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/></configSections><unity xmlns="http://schemas.microsoft.com/practices/2010/unity"><container><!--<register  type="IService.ISayHello,IService"  mapTo="Service.ChineseSayHello,Service"></register>--><register  type="IService.ISayHello,IService"  mapTo="Service.EnglishSayHello,Service"><lifetime type="singleton"/></register></container></unity><system.web><compilation debug="true" targetFramework="4.0" /></system.web>
</configuration>
View Code

我們在運行程序,得到的結果是:True,說明我們每次都引用了同一個實例,容器很好的幫我們實現了單例模式,除了singleton外,容器還默認了其他的幾種實例生命周期,這里就不在多說了。注:我們所說的實例生命周期不是指實例的創建到銷毀,而是指實例在容器中創建,受容器管轄的時間范圍。

??? Unity容器支持為一個接口或者基類注冊多個映射節點,但是每個節點需要采用不同的名稱標識,在創建實例的時候,也通過該節點名稱來創建指定的映射實例,例如

<?xml version="1.0" encoding="utf-8"?><!--有關如何配置 ASP.NET 應用程序的詳細消息,請訪問http://go.microsoft.com/fwlink/?LinkId=169433-->
<configuration><configSections><section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/></configSections><unity xmlns="http://schemas.microsoft.com/practices/2010/unity"><container><register   type="IService.ISayHello,IService"  mapTo="Service.ChineseSayHello,Service"></register><register name="english" type="IService.ISayHello,IService"  mapTo="Service.EnglishSayHello,Service"></register></container></unity><system.web><compilation debug="true" targetFramework="4.0" /></system.web>
</configuration>
View Code
using IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;namespace IOC
{public partial class Test : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){ISayHello sayhello = ServiceLocator.Instance.GetService<ISayHello>();ISayHello sayhello1 = ServiceLocator.Instance.GetService<ISayHello>("english");showInfo.InnerText = string.Format("{0}+{1}", sayhello1.hello(), sayhello.hello());//showInfo.InnerText = sayhello.GetHashCode().Equals(sayhello1.GetHashCode()).ToString();
        }}
}
View Code

結果為:hello+你好,我們成功的通過了配置文件中的注冊節點名稱來創建我們的具體服務實例。我們知道創建實例是需要調用實例的構造函數的,很顯然容器默認的為我們調用了構造函數,倘若構造函數帶有參數,則容器則會創建相應的參數實例。現在問題來了,假如我的參數是一個接口或者抽象類型怎么辦? 很顯然要能創建這樣的參數我們就必須知道參數的映射類型,?看如下例子,我們在IService項目中重新創建一個接口

using System;
using System.Collections.Generic;
using System.Linq; using System.Text; namespace IService { public interface ISay { string Say(); } }
View Code

我們寫一個服務實現該接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IService;namespace Service
{public class ComSayHello_V2 : ISay{public ISayHello Chinese { get; set; }public ComSayHello_V2(ISayHello chinese){this.Chinese = chinese;}public string Say(){return this.Chinese.hello();}}
}
View Code

配置文件如下

<?xml version="1.0" encoding="utf-8"?><!--有關如何配置 ASP.NET 應用程序的詳細消息,請訪問http://go.microsoft.com/fwlink/?LinkId=169433-->
<configuration><configSections><section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/></configSections><unity xmlns="http://schemas.microsoft.com/practices/2010/unity"><container><register   type="IService.ISayHello,IService"  mapTo="Service.ChineseSayHello,Service"></register><register name="english" type="IService.ISayHello,IService"  mapTo="Service.EnglishSayHello,Service"></register><register  type="IService.ISay,IService"  mapTo="Service.ComSayHello_V2,Service"></register></container></unity><system.web><compilation debug="true" targetFramework="4.0" /></system.web>
</configuration>
View Code
using IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;namespace IOC
{public partial class Test : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){//ISayHello sayhello = ServiceLocator.Instance.GetService<ISayHello>();//ISayHello sayhello1 = ServiceLocator.Instance.GetService<ISayHello>("english");//showInfo.InnerText = string.Format("{0}+{1}", sayhello1.hello(), sayhello.hello());//showInfo.InnerText = sayhello.GetHashCode().Equals(sayhello1.GetHashCode()).ToString();ISay say = ServiceLocator.Instance.GetService<ISay>();showInfo.InnerText=say.Say();}}
}
View Code

我們得到結果:你好。在配置文件中我們添加了兩個注冊節點,從結果中我們看見,容器默認選擇了未命名的節點,倘若我們注釋該節點程序將報錯,程序沒辦法自動識別帶名稱的節點,要想讓程序識別帶名稱的節點我們需要配置構造函數參數,配置如下

<?xml version="1.0" encoding="utf-8"?><!--有關如何配置 ASP.NET 應用程序的詳細消息,請訪問http://go.microsoft.com/fwlink/?LinkId=169433-->
<configuration><configSections><section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/></configSections><unity xmlns="http://schemas.microsoft.com/practices/2010/unity"><container><!--<register   type="IService.ISayHello,IService"  mapTo="Service.ChineseSayHello,Service"></register>--><register name="english" type="IService.ISayHello,IService"  mapTo="Service.EnglishSayHello,Service"><!--<lifetime type="singleton"/>--></register><register  type="IService.ISay,IService"  mapTo="Service.ComSayHello_V2,Service"><constructor><param name="say" dependencyName="english"></param></constructor></register></container></unity><system.web><compilation debug="true" targetFramework="4.0" /></system.web>
</configuration>
View Code

結果正確的顯示為:hello,在這里順便提一下如果我們取消english注冊節點lifetime的注釋,我們會發現每次創建ComSayHello_V2的參數將來自同一個實例的引用,原因請參見,上文的實例生命周期。
??? 當然我們也可以直接在配置文件的構造函數中指定,參數類型而避免注冊其他類型節點,配置文件代碼如下,結果一樣

<?xml version="1.0" encoding="utf-8"?><!--有關如何配置 ASP.NET 應用程序的詳細消息,請訪問http://go.microsoft.com/fwlink/?LinkId=169433-->
<configuration><configSections><section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/></configSections><unity xmlns="http://schemas.microsoft.com/practices/2010/unity"><container><register  type="IService.ISay,IService"  mapTo="Service.ComSayHello_V2,Service"><constructor><param  name="say" dependencyType="Service.EnglishSayHello,Service"></param></constructor></register></container></unity><system.web><compilation debug="true" targetFramework="4.0" /></system.web>
</configuration>
View Code

?? ?其實,我們還能夠在配置文件中給參數賦值,但是如果參數是一個復雜類型,比如類的時候,我們就需要一個轉換器,把字符串類型的值轉換為指定的賦值類型,因為在配置文件中我們賦值的類型只能是string。轉換器在平時實踐中用的少,所以我不打算多說。需要注意的是,如果我們的類中有多個構造函數的話,那么容器默認總會選擇參數最多的那個構造函數。
?? 以上所介紹的歸根到底也只是一種構造函數注入。其實Unity還提供能屬性注入與方法注入,即在創建實例的時候動態為某個屬性賦值或者調用某個方法,其實這個要做到也蠻簡單的,我們只需要在相應的屬性上面打上[Dependency]特性,在方法上打上[InjectionMethod]特性即可,但是這兩種方式對類的侵入性太強,不推薦使用

總結

??? 本文簡單的演示了Unity IOC的一些使用方法,因為在我的框架中,Unity在層次解耦中充當了重要的作用,除此之外Unity其實還能實現的AOP攔截,但是由于篇幅的原因不再多講,在這里要提醒大家務必理解實體的生命周期,因為這對實現單元工作模式有著重要的意義。在我的系列前三篇中,我都是采用了是反射來解耦,有興趣的朋友可以嘗試下用Unity取代它。我目前寫的案例與前面系列的版本框架有很大的差異,所以有些知識點必須和大家說明,相信在接下來的一到兩篇中,就能與大伙見面,祝大伙周末愉快。本篇測試源碼請點擊這里

?

轉載于:https://www.cnblogs.com/shaoshun/p/3868968.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/260197.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/260197.shtml
英文地址,請注明出處:http://en.pswp.cn/news/260197.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

后端開發需要學什么_都2020年了,還在糾結學什么語言?| 后端篇

幾個禮拜前&#xff0c;一個學弟問我&#xff1a;“Ray&#xff0c;我打算之后要找工作了&#xff0c;不過現在自己沒有特別深入的語言&#xff0c;最近想找一門好好學一下&#xff0c;你覺得學什么語言好呀&#xff1f;”我表示&#xff1a;“這個要看你求職方向、個人喜好、市…

python掃描ip的端口打開情況

我們的韓國bss系統上線之后&#xff0c;要求對主機的端口、資源使用進行統計&#xff0c;端口每個主機去看&#xff0c;太費勁了&#xff0c;所以&#xff0c;就寫了這樣一個小程序&#xff0c;不是很完美但是&#xff0c;可以用啊&#xff01;哈哈哈&#xff0c;別噴&#xff…

flash java 通信,Flash到JavaScript的通信實例

從HTML可以發送數據到Flash,反過來也可以. 這個例子演示了如何應用Flash的Fscommand來發送數據到Javascript.簡要步驟:Flash中新建一個文件,保存為flash_to_javascript.fla創建一個文本域,設置成輸入文本(Input Text),選擇"border"以便我們能看到他,指定他的變量為in…

10個非常有用的CSS hack和技術

轉自&#xff1a;http://www.qianduan.net/10-useful-css-hacks-and-technique.html 1 – 跨瀏覽器的inline-block <style>li {width: 200px;min-height: 250px;border: 1px solid #000;display: -moz-inline-stack;display: inline-block;margin: 5px;zoom: 1;*display:…

Java的遞歸算法

遞歸算法設計的基本思想是&#xff1a;對于一個復雜的問題&#xff0c;把原問題分解為若干個相對簡單類同的子問題&#xff0c;繼續下去直到子問題簡單到可以直接求解&#xff0c;也就是說到了遞推的出口&#xff0c;這樣原問題就有遞推得解。 關鍵要抓住的是&#xff1a; &…

python list遍歷定位元素_python for循環,第二遍定位不到元素?

ycyzharry: 也不行&#xff0c;我的代碼import unittestimport timeimport xlrdfrom selenium import webdriverimport seleniumdef open_excel(filefile.xls):try:data xlrd.open_workbook(file)return dataexcept Exception as e:print(str(e))def excel_table_byindex(file…

發現Java程序中的Bug

昨天在CSDN上閱讀 "Java中十個常見的違規編碼"這篇文章時&#xff0c;無意中找到了3個 "發現Java程序中的Bug"工具。 文章地址&#xff1a;http://www.csdn.net/article/2012-09-11/2809829-common-code-violations-in-java其中&#xff0c; FindBugs? - …

原生php登錄注冊,原生php登陸注冊

本以為一個登陸注冊功能十來分鐘就寫好了&#xff0c;沒想到thinkPHP用久了&#xff0c;原生的php不會寫了最開始我直接寫了類和方法&#xff0c;在前臺傳遞參數給類的login方法(action"index.php/login"),嘗試幾次發現無法訪問&#xff0c;這才意識到&#xff0c;這…

SpringMVC REST 風格靜態資源訪問配置

1 在web.xml中使用默認servlet處理靜態資源&#xff0c;缺點是如果靜態資源過多&#xff0c;則配置量會比較大&#xff0c;一旦有遺漏&#xff0c;則會造成資源無法正常顯示或404錯誤。 <!-- 靜態資源訪問控制 --><servlet-mapping><servlet-name>default<…

生成對象

var c[name,age,city]; var d[xiaogang,12,anhui]; var a{}; for(var i0;i<3;i){a[c[i]]d[i]; } console.log(a); //返回 {name: "xiaogang", age: "12", city: "anhui"} 轉載于:https://www.cnblogs.com/xiaozhumaopao/p/6046823.html

3.寄存器(內存訪問)

CPU中&#xff0c;用16位來存儲一個字。高8位存放高位字節&#xff0c;低8位存放低位字節。內存存儲中&#xff0c;內存單元是字節單元&#xff08;1單元1字節&#xff09;&#xff0c;則一個字要用兩個地址連續的內存單元存放。內存存儲中&#xff0c;高位字節&#xff0c;和低…

shiro前后端分離_為什么要前后端分離?前后端分離的優點是什么?

隨著互聯網的高速發展以及IT開發技術的升級&#xff0c;前后端分離已成為互聯網項目開發的業界標準使用方式。在實際工作中&#xff0c;前后端的接口聯調對接工作量占HTML5大前端人員日常工作的30%-50%&#xff0c;甚至會更高。接下來千鋒小編分享的廣州HTML5大前端學習就給大家…

POJ 2152 Fire

算是我的第一個樹形DP 的題&#xff1a; 題目意思&#xff1a;N個城市形成樹狀結構。現在建立一些消防站在某些城市&#xff1b;每個城市有兩個樹形cost&#xff08;在這個城市建立消防站的花費&#xff09;&#xff0c;limit &#xff1b; 我們要是每個城鎮都是安全的&#xf…

php 解析HTTP協議六種請求方法,get,head,put,delete,post有什么區別

GET&#xff1a; 請求指定的頁面信息&#xff0c;并返回實體主體。HEAD&#xff1a; 只請求頁面的首部。POST&#xff1a; 請求服務器接受所指定的文檔作為對所標識的URI的新的從屬實體。PUT&#xff1a; 從客戶端向服務器傳送的數據取代指定的文檔的內容。DELETE&#xff1a; …

python的socket連接不上_Python套接字只允許一個連接,但在新的連接上斷開,而不是拒絕...

我不確定我完全理解你的問題&#xff0c;但我認為下面的例子可以滿足你的要求。服務器可以斷開舊用戶的連接&#xff0c;為新用戶提供服務。在服務器端&#xff1a;#!/usr/bin/env pythonimport socketimport multiprocessingHOST 127.0.0.1PORT 50007# you can do your real…

dede搜索php在哪,dede搜索頁面怎么調用及相關搜索調用

dede搜索頁面怎么調用&#xff0c;那幾天有事情&#xff0c;所以導致博客幾天都一直沒有更新&#xff0c;之前我們講過dede內容頁面和dede列表模板的調用&#xff0c;今天我們一起來學習下搜索頁面的調用&#xff0c;很多做企業站朋友們都不知道dede的搜索頁怎么仿&#xff0c;…

電腦中病毒后被隱藏的文件的顯示

用批處理或DOS更改屬性。批處理就是建個記事本&#xff0c;輸入attrib -h -s -r %~dp0\*.* /s /d&#xff0c;然后另存為隨便.bat&#xff0c;把它放到那些隱藏文件夾外面&#xff08;不是里面&#xff09;&#xff0c;然后雙擊打開&#xff0c;等它自己關閉窗口就好了轉載于:h…

HDU 3555 - Bomb

第一道數位dp&#xff0c;屬于基礎模板&#xff0c;又自卑小時沒學好數數了&#xff0c;只是不清楚為什么大家的dp定義都是相同的&#xff0c;很顯然么&#xff0c;難道我寫的是怪胎。。。 /* ID:esxgx1 LANG:C PROG:hdu3555 */ #include <cstdio> #include <cstring&…

瀏覽器angent分析工具

cz.mallat.uasparser.UserAgentInfo info null; info uasParser.parse(userAgent);轉載于:https://www.cnblogs.com/yaohaitao/p/6048011.html

python2協程_python中的協程(二)

協程1、協程&#xff1a;單線程實現并發在應用程序里控制多個任務的切換保存狀態優點&#xff1a;應用程序級別速度要遠遠高于操作系統的切換缺點&#xff1a;多個任務一旦有一個阻塞沒有切&#xff0c;整個線程都阻塞在原地&#xff0c;該線程內的其他的任務都不能執行了一旦引…