ASP.NET2.0选用中定制安全凭证之实践篇

import
java.util.concurrent.ArrayBlockingQueue;

① 、方案架构

import
java.util.concurrent.BlockingQueue;

  本方案架构很简短——它用叁个Web服务来包装ASP.NET
2.0提供者并且为远程客户暴光该证据管理,你居然还是能在该架构中加上一些失去的效劳。然后,在提供1个添加的用户接口和周到凭证管理经验的还要,使用3个Windows表单应用程序来开支该Web服务。该Web服务配置文件将涵盖特定于该证据存款和储蓄的授命。不过,那确实意味着全体由该Web服务管理的应用程序都将得以共享那些指令。

import
java.util.concurrent.ExecutorService;

  纵然你可以起初到尾地塑造该Web服务,约等于说,首先用静态方法Roles和Membership来包装它们并定义该Web服务,笔者却更爱好一种契约驱动的章程:首先设计执行各类操作的最好接口将是哪些,并且直到须要时才考虑怎么着贯彻它们。这样做能够有限扶助由Web服务暴露的接口帮助具有要求的保管成效并且还将压缩该客户应用程序与其余达成细节(例如包装提供者)之间的耦合。

import
java.util.concurrent.Executors;

   ASP.NET
2.0的贰个更好的特性是它支持Web服务接口,你能够定义并且让该Web服务揭破逻辑接口,就象类的表现一样。为此,你须要用
Web瑟维斯Binding属性修饰你的接口并且经过WebMethod属性来暴光单个的接口方法。然后,你将有三个派生于那个接口的类并实现该接口,而且编写翻译器将须要您辅助该接口的富有办法。

 

  为了管住和互相于凭证存款和储蓄和Web服务配置,小编定义了5个接口-IApplicationManager,IMembershipManager,IPasswordManager,IroleManager和IUserManager。

/**

  (一) IApplicationManager

   
本例介绍贰个异样的行列:BlockingQueue,借使BlockQueue是空的,从BlockingQueue取东西的操作将会被堵嘴进入等待意况,直到BlockingQueue进了事物才会被唤醒.同样,尽管BlockingQueue是满的,任何试图往里存东西的操作也会被堵嘴进入等待状态,直到BlockingQueue里有空间才会被提示继续操作.

  该IApplicationManager接口展现于所附源码中的列表2,允许管理员删除一钦点的应用程序-也等于说,从数据库中删除全部到它的参照并且删除它的享有用户和剧中人物。IApplicationManager允许从存款和储蓄中去除全部的应用程序,并且它能回去在该存款和储蓄中的全部应用程序的多个列表。注意,这几个接口作为1个里头的接口被定义-public或internal可知性修饰词对Web服务接口都是虚幻的。该接口上的每一个方法用
WebMethod属性加以修饰并有三个该措施的简短描述。其余,存取凭证存储的兼具办法都被安装为使用事务处理。那样的话,三种操作-如删减一应用程序和创立一用户将在相互完全隔断的景色下实施,从而确认保障了如删减全部用户等繁杂操作的原子性。.NET
2.0中的Web服务只可以运行一个新工作,而且它是由WebMethod属性的TransactionOption属性来控制的。最终一点是把
WebServiceBinding属性应用于接口上。那就内定该接口是3个客户和服务都能绑定到的Web服务接口。为了把该接口以1个WSDL契约格局暴光给外界,你需求运用一个shim类。那几个shim类的布署性是不可或缺的,因为您无法把多少个接口作为一Web劳务暴光,而且你也无法在其上应用
WebService属性。这一个shim类还将经由WebService属性为该接口命名空间定义。上边包车型地铁代码突显了
IApplicationManagerShim抽象类的定义。

   
本例再度落实11.4线程—-条件Condition中介绍的篮子程序,不过那个篮子中最多能放的苹果数不是1,能够随便钦定.当篮子满时,生产者进入等待情形,当篮子空时,消费者等待.

[WebService(Name=”IApplicationManager”,
Namespace=”http://CredentialsServices“,
Description=”IApplicationManager is used to manage
applications. This web service is only
the definition of the interface. You
cannot invoke method calls on it.”)]
abstract class IApplicationManagerShim : IApplicationManager{
 public abstract void DeleteApplication(string application);
 public abstract string[] GetApplications();
 public abstract void DeleteAllApplications();
}

 */

  因为IApplicationManagerShim是叁个类,所以您能够把它揭露为1个Web服务。因为它是一抽象类且具有办法被定义为架空方法,所以不供给(也无法)实现别的方法。为了使其看起来就象该接口,IapplicationManagerShim把WebService属性的习性名设置为
IApplicationManager(代替缺省的类名)。今后,你能够选用IApplicationManager.asmx文件来揭穿该接口。

/**

<%@ WebService Language=”C#”
CodeBehind=”~/App_Code/IApplicationManagerShim.cs”
Class=”IApplicationManagerShim”%>

   
使用BlockingQueue的机要技术点如下:

  以后,假若您浏览到IApplicationManager.asmx页面,你就晤面到该接口定义。你能够应用WSDL.exe的serverInterface选项来把接口定义输入到客户端或任何别的想绑定到该接口定义上的劳务。

   
1.BlockingQueue定义的常用方法如下:

  (二) IMembershipManager

   
    1)add(anObject):把anObject加到BlockingQueue里,即假若BlockingQueue能够包容,则赶回true,否则招聘非常

  IMembershipManager接口(见所附源码中的列表3)允许你管理用户帐户的全体方面-创制和删除用户帐户,更新用户帐户,检索用户帐户细节以及查找在一应用程序中的全部用户。

   
    2)offer(anObject):表示只要或许的话,将anObject加到BlockingQueue里,即只要BlockingQueue能够包容,则赶回true,否则重返false.

  (三) IRoleManager

   
    3)put(anObject):把anObject加到BlockingQueue里,要是BlockQueue没有空间,则调用此格局的线程被阻断直到BlockingQueue里面有空间再继续.

  IRoleManager接口允许你管理逻辑角色的持有地方-成立和删除剧中人物,从角色中加进和删除用户以及查找在一应用程序中的全数剧中人物。

   
    4)poll(time):取走BlockingQueue里排在第二人的靶子,若不能够登时取出,则足以等time参数规定的时日,取不到时回来null

[WebServiceBinding(“IRoleManager”)]
interface IRoleManager{
[WebMethod(…)]
void CreateRole(string application,string role);
[WebMethod(…)]
bool DeleteRole(string application,string role,bool
throwOnPopulatedRole);
[WebMethod(…)]
void AddUserToRole(string application,string userName, string role);
[WebMethod(…)]
void DeleteAllRoles(string application,bool throwOnPopulatedRole);
[WebMethod(…)]
string[] GetAllRoles(string application);
[WebMethod(…)]
string[] GetRolesForUser(string application,string userName);
[WebMethod(…)]
string[] GetUsersInRole(string application, string role);
[WebMethod(…)]
void RemoveUserFromRole(string application,string userName, string
roleName);
//更加多成员
}

   
    5)take():取走BlockingQueue里排在第三位的对象,若BlockingQueue为空,阻断进入等待处境直到Blocking有新的指标被投入截至

  (四) IPasswordManager

   
2.BlockingQueue有八个有血有肉的贯彻类,依据分裂要求,选拔不一致的落实类

  这几个IPasswordManager接口首要提供与应用程序口令策略相关的只读音信。

       
1)ArrayBlockingQueue:规定大小的BlockingQueue,其构造函数必须带二个int参数来指明其大小.其所含的靶子是以FIFO(先入先出)顺序排序的.

[WebServiceBinding(“IPasswordManager”)]
interface IPasswordManager{
[WebMethod(…)]
bool EnablePasswordReset(string application);
[WebMethod(…)]
bool EnablePasswordRetrieval(string application);
[WebMethod(…)]
string GeneratePassword(string application,int length,
int numberOfNonAlphanumericCharacters);
[WebMethod(…)]
bool RequiresQuestionAndAnswer(string application);
[WebMethod(…)]
string ResetPassword(string application,string userName);
[WebMethod(…)]
string GetPassword(string application,string userName,string
passwordAnswer);
[WebMethod(…)]
void ChangePassword(string application,string userName,string
newPassword);
//越来越多成员
}

       
2)LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带2个规定大小的参数,生成的BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的高低由Integer.MAX_VALUE来决定.其所含的靶子是以FIFO(先入先出)顺序排序的

  典型地,该策略存款和储蓄在应用程序的安顿文件中。该方针包蕴是或不是运转口令重置和搜索,口令强度和口令回答策略等。你也得以采取IpasswordManager来生成一相应于该口令强度策略的新口令。此外,IpasswordManager可用于重置、改变或探寻一钦赐用户的口令。

       
3)PriorityBlockingQueue:类似于LinkedBlockQueue,但其所含对象的排序不是FIFO,而是基于对象的当然排序依次大概是构造函数的Comparator决定的顺序.

  (五) IUserManager

       
4)SynchronousQueue:特殊的BlockingQueue,对其的操作必须是放和取交替实现的.

  IUserManager接口允许校验用户凭证,检索剧中人物地位以及取得钦定用户是其成员之一的保有剧中人物。该接口用于测试和剖析指标。

   
3.LinkedBlockingQueue和ArrayBlockingQueue相比较起来,它们背后所用的数据结构不平等,导致LinkedBlockingQueue的数量吞吐量要超过ArrayBlockingQueue,但在线程数量相当大时其性质的可预知性低于ArrayBlockingQueue.   
     

[WebServiceBinding(“IUserManager”)]
public interface IUserManager{
[WebMethod(…)]
bool Authenticate(string applicationName,string userName, string
password);
[WebMethod(…)]
bool IsInRole(string applicationName,string userName, string role);
[WebMethod(…)]
string[] GetRoles(string applicationName,string userName);
}
二、AspNetSqlProviderService Web服务

 */

  展现在所附源码中的列表4中的
AspNetSqlProviderService类落成了七个Web接口。其进程就象实现别的其余接口一样-你能够隐式或显式地派生并落到实处方式(见列表
4)。作者是由此把那几个完成简单地代理到提供者的确切的办法来落到实处该Web接口上的绝半数以上主意的。在每3回利用角色或地方此前,你必须为之作好准备-通过安装要采用的应用程序名。例如,为了兑现IRoleManager.CreateRole(),你将须求建立:

public
class
BlockingQueueTest {

void IRoleManager.CreateRole(string application,string role){
Roles.ApplicationName = application;
Roles.CreateRole(role);
}

      
/**概念装苹果的篮筐*/

  在那之中的一些办法在调用该提供者前后还须要一点工作。例如,假设开发银行口令检索,你不得不寻找用户口令,而AspNetSqlProviderService则用于判定它。

      
public
static
class
Basket{

string IPasswordManager.GetPassword(string application,string
userName,
string passwordAnswer){
Membership.ApplicationName = application;
Debug.Assert(Membership.EnablePasswordRetrieval);
MembershipUser membershipUser =Membership.GetUser(userName);
return membershipUser.GetPassword(passwordAnswer);
}

      
       //篮子,能够容纳三个苹果

  然则,还有一对艺术并不曾到手提供者的第③手援助。有二种只怕的消除办法-第二种是尝尝并使用提供者的其他方法来达成所企盼的操作。第1种是一直实施
aspnetdb数据库。二种艺术都设有利弊。例如,可以设想完毕MembershipManager.DeleteAllUsers()方法。你能够对该应用程序中的每种用户调用身份提供者的DeleteUser()方法,如列表4所示。首先你要调用
IMembershipManager.GetAllUsers()方法来博取应用程序中的全部用户。那便是你通过兑现该接口的类来选取该接口方法的显式落成情势。然后,你能够定义1个匿超格局来删除用户,把该匿超级模特式赋值到2个Action<string>代理,并且动用Array类的静态方法
ForEach<T>()删除每一个用户。

      
       BlockingQueue<String> basket =
new
ArrayBlockingQueue<String>(3);

public delegate void Action<T>(T obj);
public abstract class Array : …
{
public static void ForEach<T>(T[] array,Action<T> action);
}

      
       //生产苹果,放入篮子

  第1种办法的独到之处是别的与删除二个用户相关的里边活动(如也删除全数的剧中人物身份)照旧被实践。其不足是,你须求对该数据库做更加多的调用。

      
       public
void
produce() throws
InterruptedException{

  正如刚刚提到的,第两种形式是一直对aspnetdb数据库编制程序。当提供者没有提供别的方法来实现此职责时,那是最得力的。例如,提供者并不扶助删除一应用程序,更不说删除全部的应用程序了。固然你能够编写制定3个储存进程来做那件业务,但本身的另三个指标是不采纳aspnetdb,而是利用原始SQL命令来落到实处IApplicationManager.DeleteApplication()和
IApplicationManager.DeleteAllApplications()。小编已用1个AspNetDbTablesAdapter助理类(在此并未出示)包装了这个命令。直接待上访问数据库的优点是你仅执行3个命令;不足之处是,假设要转移数据库形式,你将索要变更你的代码。假定如删减全数的用户或一应用程序等操作是相似不涉及的同时一流用户的数据日常十分小,那么小编想最好尽也许让AspNetSqlProviderService使用
ASP.NET 2.0提供者。

      
              //put方法放入二个苹果,若basket满了,等到basket有岗位

  (一) 设置服务

      
              basket.put(“An
apple”);

  由AspNetSqlProviderServiceWeb服务应用的Web.Config文件中的设置影响它管理的有所应用程序。尤其地,如口令策略那样的安装适用于拥有的应用程序。该服务使用暗中同意提供者
(SQL
SE福特ExplorerVEGL450),由此只要缺省的接连字符串(在文书machine.config中爱戴)已经丰硕的话,就不须要钦赐一个提供者甚至贰个连接字符串。要是您要求一个不比的连天字符串,你供给包蕴五个connectionStrings标签(见所附源码中的列表5)。此外,为了利用Roles类,你必须经过下列指令来运行基于角色的荆门。

      
       }

<roleManager enabled=”true” />

      
       //消费苹果,从篮子中取走

  (二) 爱抚服务

      
       public
String consume() throws
InterruptedException{

  就算其证据由AspNetSqlProviderServiceWeb服务来管理的应用程序恐怕是基于网络或依照内部网的,不过服务本人是被设计由3个总指挥通过本地内部网来存取的。你应有辨证和授权到该服务的调用。其它,你还相应通过加密报道来提供隐私服务。这是讲求的,因为该服务要拍卖如用户名和口令等趁机音讯。保证机密的最不难的点子是采纳HTTPS。
AspNetSqlProviderService在它的构造器中途经静态VerifySecureConnection()助理方法来展开认证是还是不是采纳了1个安全连接。VerifySecureConnection()使用当前乞求的IsSecureConnection属性。为了协助开发或该服务的其他品类的非生产性宣布,VerifySecureConnection()方法用Conditional属性加以修饰。只有定义编写翻译符号HTTPS时该格局才会起成效。关于认证该服务的用户,既然Web服务是一地面内部网服务,那么使用Windows认证就不会有其余错误了。笔者选取了利用集成的
Windows认证-那将节省了用户必须旗帜鲜明地登录的艰巨。集成的辨证的其余八个优点是,它用一种专利情势来散列化发送过去的凭据。

      
              //take方法取出3个苹果,若basket为空,等到basket有苹果截止

  为了布署集成的Windows认证,转到在IIS下的AspNetSqlProviderServiceWeb服务天性,选用目录安全选项卡,并且点击”艾德it…”按钮。不采取”Anonymous
access”复选框并且保证选中”Integrated Windows
authentication”复选框。AspNetSqlProviderService类被安排以要求验证(见列表4)-它利用
PrincipalPermission属性并把被证实的属性设计为true。

      
              return
basket.take();

[PrincipalPermission(SecurityAction.Demand,…,Authenticated=true)]

      
       }

  一旦调用者通过IIS被认证,该服务缺省级地区级将在IIS中以安顿的地位如故运营。笔者想以调用者身份运营该服务。为此,Web.Config文件(见列表5)包罗了三个identity标签-它把impersonate属性设置为true。

      
}

<identity impersonate=”true”/>

      
//测试方法

  然后,你要求选用SQL
SE奥迪Q7VE奥迪Q5管理工科具来允许Web服务的调用者从aspnetdb数据库中实行读和写。

      
public
static
void
testBasket(){

  爱抚该Web服务的另3个注重地方是授权。作者想要验证唯有Windows一流用户组的成员才能存取这一服务。为此,AspNetSqlProviderService类上的PrincipalPermission属性供给唯有一级用户剧中人物的积极分子才被允许行使该服务。

      
       final
Basket basket = new
Basket();//建立贰个装苹果的篮子

[PrincipalPermission(SecurityAction.Demand,
Role = “Administrators”,…)]

      
       //定义苹果生产者

  你能够用此外别的组(该服务的实际上用户应该是内部的一员)来替换”Administrators”。

      
       class
Producer implements
Runnable{

  PrincipalPermission属性使用配属于该线程的白山领导(principal)来证实调用者是不是确实是内定剧中人物中的一员。在借助于NT组(如一级用户)时,那将劫持你使用二个WindowsPrincipal的实例。

      
              public
void
run(){

public class WindowsPrincipal : IPrincipal{
 public WindowsPrincipal(WindowsIdentity ntIdentity);
 public virtual bool IsInRole(string role);
 //此外成员部分
}

      
                     try{

  难点在于,为了选择Roles类,AspNetSqlProviderServiceWeb.Config文件必须运营基于剧中人物的安全策略。

      
                            while(true){

<roleManager enabled=”true” />

      
                                   //生产苹果

  那反过来使得ASP.NET
2.0把一不等的principal依附到HttpContext和线程上,当然还有RolePrincipal类。

      
                                   System.out.println(“生产者准备生育苹果:
” +
System.currentTimeMillis());

public sealed class RolePrincipal : IPrincipal{…}

      
                                   basket.produce();

  在NT一级用户剧中人物中间试验图使用RolePrincipal和过度须求的地点将会破产,因为它将存取aspnetdb而不是Windows组来搜寻它。为补偿那或多或少,你不能够不手工业地调换这么些领导同时在每一回请求时把WindowsPrincipal的四个实例依附到该线程上。为此,最简单的不二法门是把二个Global.asax文件添加到该Web服务工程-通过点名在Global.cs文件中的Global类为类后的代码。

      
                                   System.out.println(“生产者生产苹果完结:
” +
System.currentTimeMillis());

<%@ Application Language=”C#” CodeBehind =”Global.cs” Inherits =
“Global”%>

      
                                   //休眠300ms

  这些Global类为应用程序授权请求提供一个计算机。

      
                                   Thread.sleep(300);

public class Global : HttpApplication{
 protected void Application_AuthorizeRequest(object sender, EventArgs
e){
  if(HttpContext.Current.User.Identity.IsAuthenticated){
   WindowsIdentity identity = HttpContext.Current.User.Identity as
WindowsIdentity;
   Debug.Assert(identity != null);
   WindowsPrincipal principal;
   principal = new WindowsPrincipal(identity);
   Thread.CurrentPrincipal = principal;
  }
 } 
}

      
                            }

  就算调用者被证实,那么您须要实例化一新的WindowsPrincipal对象并且把它依附于当下线程。WindowsPrincipal构造器需求2个WindowsIdentity的实例。幸亏,因为该服务正在使用Windows集成的验证,在功成名就验证后,与当下HTTP上下文相联系的地位早已是
WindowsIdentity类型了,因而你能够只获得这么些实例。
**③ 、凭证管理器应用程序

      
                     }catch(InterruptedException
ex){

**  本文相应的源代码包括了那些证据管理器应用程序-一个具有足够的用户接口的Windows表单应用程序,它利用在上一步描述的Web服务接口来为别的数据的应用程序管理安全凭证存储。

      
                     }

  该应用程序导入七个Web接口定义,并且它独占地使用这些接口。该应用程序有二个名为AspNetSqlProviderService的Web服务代办类-它用来固定该服务。你须求从导入的接口手工业地把它添加到该服务上。

      
              }

图片 1
图4.Applications选项卡:那一个选项卡让您选拔要配备的应用程序。

      
       }

partial class AspNetSqlProviderService :
SoapHttpClientProtocol,IMembershipManager,
IUserManager,IPasswordManager,
IApplicationManager,IRoleManager
{
 public AspNetSqlProviderService (){
  Credentials = CredentialCache.DefaultCredentials;
  Url = Settings.Default.AspNetSqlProviderService ;
 }
 //别的的履行
}

      
       //定义苹果消费者

  为了补助集成的Windows认证,那个代理类的构造器使用CredentialCache的静态属性DefaultCredentials设置凭证属性-它只是简短地读取当前线程的安全标志。此外,这么些构造器还采取设计器生成的Settings类从应用程序配置类中读取Web服务地点。

      
       class
Consumer implements
Runnable{

图片 2
图5.Users选项卡:该选项卡列出在选定的应用程序中的全体用户。

      
              public
void
run(){

  这些应用程序的行使相当直观,所以自个儿只介绍一下重中之重荧屏和抉择。Applications选项卡(见图4)允许你挑选要安插的应用程序。

      
                     try{

  在此,选取一应用程序将震慑全数其余的选项卡。你能够创设和删除多少个应用程序或删除全体应用程序。Users选项卡列举出在甄选的应用程序中的全部用户。

      
                            while(true){

  你能够创造或删除一用户。如若您剔除一用户但是不选择”All
Data”复选框的话,它将去除该用户但是保持它的剧中人物身份消息。你能够更新一用户帐户或删除全体用户。依照从
AspNetSqlProviderServiceWeb服务再次回到的口令策略的不等,你能够或不可能改变或重置口令,而且能够或不得以须求应对该口令。在Users选项卡的按钮和它所体现的对话框也对应地运维或取缔。

      
                                   //消费苹果

  在Users选项卡的左边是总括新闻,如当前用户的在线数。Roles选项卡允许你把剧中人物添加到应用程序。

      
                                   System.out.println(“消费者准备消费苹果:
” +
System.currentTimeMillis());

图片 3
图6:Roles选项卡:那些选项卡让你把剧中人物添加到应用程序。

      
                                   basket.consume();

  当删除一个剧中人物时,假使您选用了”Fail if
populated”复选框,那么一旦它有此外成员来说,就不会让您删掉该剧中人物。右边的列表视图呈现在该应用程序中的全部用户。你能够从三个剧中人物添加或删除一用户,或从持有剧中人物中删去一用户。在底部,”Users
in role”列表框展现了在上边选定的剧中人物中的全数用户,而”Roles for
User”列表框显示了在上头选定的用户中的全数剧中人物。

      
                                   System.out.println(“消费者消费苹果完成:
” +
System.currentTimeMillis());

  Passwords选项卡展现在图7中,它列出已布置的口令策略并且同意你生成一与内定的口令强度策略相匹配的新口令。

      
                                   //休眠1000ms

图片 4
图7.Passwords选项卡:你能够应用这一个选项卡生成一口令。

      
                                   Thread.sleep(1000);

图片 5
图8.Credentials 瑟维斯选项卡:使用那一个选项卡来挑选选用的Web服务。

      
                            }

  该选项卡让你挑选要选取的Web服务。一旦运维,凭证管理器应用程序即从应用程序配置文件中读取那几个地方。那几个选项卡显示被选用的Web服务。借使地点是无用的,也等于说,该服务不匡助全数供给的效果,那么在应用程序中的全数控件都将为空且是不准的。你能够提供二个例外的地点,而下边包车型客车Web浏览器控件将会显示这一劳动。但是,如若该服务支撑供给的Web方法(一一蹴而就的Web服务)的话,你能够只选取3个Web服务地点(通过点击Select按钮)。假诺该服务是无用的,那么将禁止Select按钮。

      
                     }catch(InterruptedException
ex){

  不幸的是,在.NET
2.0中绝非提供销商业高校验某服务是还是不是支持一专程绑定或Web接口的放置帮忙,因此小编只可以手工业落成。所附源码中的列表6显得出
RefreshSelectButton()和ContainsInterface()助理方法。RefreshSelectButton()首先禁止
Select按钮和相匹配的菜单项。然后,验证钦赐的地址是二个.NET
Web服务的地点。然后,它存取呈现在Web浏览器控件中的页面包车型大巴剧情还要证实它含有扶助具备的接口的办法。为此,它要调用
ContainsInterface()方法并把页面包车型大巴剧情和要表明的接口类型提供给它。ContainsInterface()验证该品种是2个接口的档次并且取得一个MethodInfo对象数组-标记在该接口上的每一个方法。然后,它定义贰个收下单个实例MethodInfo的匿名情势并且采纳字符串类的Contains()方法来表明该内容包蕴那些情势。ContainsInterface()使用该数组类的静态TrueForAll<T>()方法。

      
                     }

public delegate bool Predicate<T>(T obj);
public abstract class Array : …
{
 public static bool TrueForAll<
 T>(T[] array,Predicate<
 T> match);
}

      
              }

  ContainsInterface()提须求TrueForAll()一个MethodInfo对象数组和匿名情势形式的Predicate。只有在该内容中找到全部的方式时,TrueForAll<T>()才回来true。
http://www.7dspace.com/doc/24/0512/2005123006395536935_1.htm

      
       }

      
       ExecutorService service =
Executors.newCachedThreadPool();

      
       Producer producer = new
Producer();

      
       Consumer consumer = new
Consumer();

      
       service.submit(producer);

      
       service.submit(consumer);

      
       //程序运转5s后,全体职分停止

      
       try{

      
              Thread.sleep(5000);

      
       }catch(InterruptedException
ex){

      
       }

      
       service.shutdownNow();

      
}

      
public
static
void
main(String[] args){

      
       BlockingQueueTest.testBasket();

      
}

}