zoukankan      html  css  js  c++  java
  • 关于 Container ,Injection

    1.容器的历史

    容器概念始于 1979 年提出的 UNIX chroot,它是一个 UNIX 操作系统的系统调用,将一个进程及其子进程的根目录改变到文件系统中的一个新位置,让这些进程只能访问到这个新的位置,从而达到了进程隔离的目的。

    2000 年的时候 FreeBSD 开发了一个类似于 chroot 的容器技术 Jails,这是最早期,也是功能最多的容器技术。Jails 英译过来是监狱的意思,这个“监狱”(用沙盒更为准确)包含了文件系统、用户、网络、进程等的隔离。

    2001 Linux 也发布自己的容器技术 Linux VServer,2004 Solaris 也发布了 Solaris Containers,两者都将资源进行划分,形成一个个 zones,又叫做虚拟服务器。

    2005 年推出 OpenVZ,它通过对 Linux 内核进行补丁来提供虚拟化的支持,每个 OpenVZ 容器完整支持了文件系统、用户及用户组、进程、网络、设备和 IPC 对象的隔离。

    2007 年 Google 实现了 Control Groups( cgroups ),并加入到 Linux 内核中,这是划时代的,为后期容器的资源配额提供了技术保障。

    2008 年基于 cgroups 和 linux namespace 推出了第一个最为完善的 Linux 容器 LXC。

    2013 年推出到现在为止最为流行和使用最广泛的容器 Docker,相比其他早期的容器技术,Docker 引入了一整套容器管理的生态系统,包括分层的镜像模型,容器注册库,友好的 Rest API。

    2014 年 CoreOS 也推出了一个类似于 Docker 的容器 Rocket,CoreOS 一个更加轻量级的 Linux 操作系统,在安全性上比 Docker 更严格。

    2016 年微软也在 Windows 上提供了容器的支持,Docker 可以以原生方式运行在 Windows 上,而不是需要使用 Linux 虚拟机。

    基本上到这个时间节点,容器技术就已经很成熟了,再往后就是容器云的发展,由此也衍生出多种容器云的平台管理技术,其中以 kubernetes 最为出众,有了这样一些细粒度的容器集群管理技术,也为微服务的发展奠定了基石。因此,对于未来来说,应用的微服务化是一个较大的趋势。

    为什么需要容器

    其一,这是技术演进的一种创新结果,其二,这是人们追求高效生产活动的一种工具。

    随着软件开发的发展,相比于早期的集中式应用部署方式,现在的应用基本都是采用分布式的部署方式,一个应用可能包含多种服务或多个模块,因此多种服务可能部署在多种环境中,如虚拟服务器、公有云、私有云等,由于多种服务之间存在一些依赖关系,所以可能存在应用在运行过程中的动态迁移问题,那这时如何保证不同服务在不同环境中都能平滑的适配,不需要根据环境的不同而去进行相应的定制,就显得尤为重要。

    就像货物的运输问题一样,如何将不同的货物放在不同的运输机器上,减少因货物的不同而频繁进行货物的装载和卸载,浪费大量的人力物力。

    为此人们发明了集装箱,将货物根据尺寸形状等的不同,用不同规格的集装箱装载,然后再放到运输机上运输,由于集装箱密封,只有货物到达目的地才需拆封,在运输过程能够再不同运输机上平滑过渡,所以避免了资源的浪费。

    Injection

    javava EE CDI主要使用@Inject批注,以便将托管bean的依赖注入执行到其他容器托管资源。

    构造函数依赖注入

    构造函数依赖注入
    公共类SomeBean {
      
      私人最终服务;
    
      @注入
      public SomeBean(服务服务){
        this.service = service;
      }
    
    }

    当CDI容器实例化SomeBean类型的bean时,它将查找默认(无参数)构造函数并使用它来创建bean实例。这个规则的例外是当我们有另一个用@Inject注释的构造函数时如果是这种情况,容器将使用带注释的构造函数,并将注入作为构造函数参数传递的依赖项。

    在上面的示例中,它将获取一个Service实例并注入SomeBean带注释的构造函数。

    注意:请记住,它可能只存在一个单一的与@Inject注释构造函数

    场依赖注入

    场依赖注入
    公共类SomeBean {
      
      @注入
      私人服务;
    
    }

    在这种情况下,当容器初始化类型为SomeBean的bean时,它会将正确的Service bean注入到字段中,即使它是私有的,也不需要任何setter方法。

    Initializer方法依赖注入

    Initializer方法依赖注入
    公共类SomeBean {
      
      私人服务;
      
      @注入
      public void setService(服务服务){
        this.service = service;
      }
    
    }

    在这种情况下,当容器初始化SomeBean类型的bean时,它将调用所有使用@Inject注释的方法,并将依赖项注入方法参数。

    @Any资格赛

    为了提供完全松散耦合的应用程序,我们通常将接口注入托管资源。如果我们为给定的接口提供多个bean实现怎么办?我们可以使用@Any限定符以及CDI 实例接口将它们全部注入到托管bean中

    @Any资格赛
    公共类SomeBean {
      
      @注入
      public void listServiceImplementations
          @Any Instance <Service> serviceList){
    
        for(服务服务:serviceList){
          System.out.printlnservice.getClass()另一方面,getCanonicalName());
        }
    
      }
    }

    @Any预选赛指示,该注射点可以通过任何可用的依赖性得到满足的容器,因此容器注入他们。如果我们有多个接口实现并且我们只注入一个 - 没有任何消除歧义 - 容器会抱怨并且无法初始化组件。我们将在其他教程中看到依赖消歧。

    注入生产者方法

    生产者方法参数也可以由CDI容器注入。请参阅Java EE CDI Producer方法教程

    CDI代理

    本教程将不完整,我们也没有涵盖CDI代理机制。当我们注入被以不同于一个范围内创建一个托管bean @Dependent -到另一个托管的资源- CDI容器也没有注入直接引用注入豆。

    对于CDI bean范围,请参阅Java EE CDI bean范围

    为什么CDI使用代理?因为如果注入直接bean引用,就会产生线程安全或对托管bean的并发访问等问题。

    想象一下,会话范围的bean被注入到应用程序范围的bean中。由于应用程序作用域bean在所有客户端之间共享,如果多个客户端同时访问应用程序作用域bean,则存在一个客户端访问另一个客户端直接引用的会话作用域bean的高风险。

    要解决此问题,CDI会创建代理并将代理注入注入点。然后,代理将处理对注入的bean的调用,并将调用转发给正确的bean实例。

    CDI创建的代理扩展了注入bean的类。想象一下以下场景:

    应用程序和会话范围的bean
    @SessionScoped
    公共课堂服务{
    
      public void doWork(){
        System.out.println “工作......”);
      }
    
    }
    
    
    @ApplicationScoped
    公共类SomeBean {
      
      @注入
      私人服务;
      
      public void test(){
        service.doWork();
      }
    
    }

    CDI会将会话作用域bean的代理注入到应用程序作用域bean中。对会话范围bean的每次调用都将通过代理,代理又将调用重定向到正确的会话bean实例:属于当前HTTP请求会话的实例。

    CDI通过扩展bean类并覆盖所有非私有方法来创建代理。代理的代表性说明可能如下:

    说明性的CDI代理
    公共类服务$ Proxy $ _ $$ _ WeldClientProxy
      扩展服务{
    
      @覆盖
      public void doWork(){
        Service instance = // ...解析bean实例
        instance.doWork();
      }
    
    }

     

     
     
     
     
     
  • 相关阅读:
    简单分页案例
    layer弹出层
    layDate 日期与时间组件 入门
    error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools":解决方案
    eclipse常用快捷键
    javascript DOM编程艺术(第2版)
    webstorm破解
    Intellij IDEA搭建vue-cli项目
    颜色rgba、hsla
    文本阴影、换行、溢出
  • 原文地址:https://www.cnblogs.com/LeshengW/p/10493387.html
Copyright © 2011-2022 走看看