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.println(service.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();
} }
 
 
 
 
 

关于 Container ,Injection的更多相关文章

  1. Container&injection

    容器(Container)就是组件和底层服务细节之间的接口.在web组件.企业级Bean等能够执行之前,它必须被装配为一个JavaEE模块,并部署在容器上. 在JavaEE5时代通过注解的方式注入(i ...

  2. Container&injection(容器与注入思想)

    container 为了更好理解JAVA容器,查询了容器的概念以及容器的诞生原因和历史: 容器技术是怎么一个概念呢?其实,IT里的容器技术是英文单词Linux Container的直译.contain ...

  3. container/injection简介以及发展历史

    一:什么是Container?Container的作用? 容器是一个标准的软件单元,它将代码及其所有依赖关系打包,以便应用程序从一个计算环境快速可靠地运行到另一个计算环境.container的主要作用 ...

  4. Java EE ----- Container/Injection

    容器(container)是一个类,实际上是component的子类,因此容器本身也是一个组件,具有组件的所有性质,但是它的主要功能是容纳其他组件和容器. 对于开发人员,需要引入复杂的代码解决事务以及 ...

  5. Container/Injection

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

  6. 为什么会出现container/injection的思想?

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

  7. Container/Injection 为什么会出现容器的思路,以后会有什么的趋势,未来是怎样的

    一.为什么会出现容器的思路? 容器概念始于 1979 年提出的 UNIX chroot,它是一个 UNIX 操作系统的系统调用,将一个进程及其子进程的根目录改变到文件系统中的一个新位置,让这些进程只能 ...

  8. container injection——容器技术

    (一)容器技术为什么出现 在很久很久以前,想要在线上服务器部署一个应用,首先需要购买一个物理服务器,在服务器安装一个操作系统,然后安装好应用所需要的各种依赖环境,最后才可以进行应用的部署,而且一台服务 ...

  9. weblogic环境,应用上传图片报Could not initialize class sun.awt.X11.XToolkit

    问题描写叙述 遇到的问题是在weblogic环境,应用在上传图片的时候报Could not initialize class sun.awt.X11.XToolkit 错误. 详细错误例如以下 17: ...

  10. Container and Injection in Java

    一.Container 1.为什么使用Container 通常,瘦客户端多层应用程序很难编写,因为它们涉及处理事务和状态管理.多线程.资源池和其他复杂的低级细节的复杂代码行.基于组件和独立于平台的Ja ...

随机推荐

  1. java中经常使用的Swing组件总结

    1.按钮(Jbutton) Swing中的按钮是Jbutton,它是javax.swing.AbstracButton类的子类,swing中的按钮可以显示图像,并且可以将按钮设置为窗口的默认图标,而且 ...

  2. 测试教程网.unittest教程.4. 实例: 读取测试数据并测试弱密码

    From: http://www.testclass.net/pyunit/test_example_2/ 背景 接上一节的弱密码例子,我们的用例尽管运行的不错,但还是有点问题. 假如我们需要增加一些 ...

  3. uoj#187. 【UR #13】Ernd

    http://uoj.ac/problem/187 每个点只能从时间,b+a,b-a三维都不大于它的点转移过来,将点按时间分成尽量少的一些段,每段内三维同时非严格单调,每段内的点可能因为连续选一段而产 ...

  4. 峰Redis学习(9)Redis 集群(概述)

    第一节:Redis 集群概述 redis cluster是去中心化,去中间件的,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态.每个节点都和其他所有节点 ...

  5. PAT 乙级 1036 跟奥巴马一起编程(15) C++版

    1036. 跟奥巴马一起编程(15) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 美国总统奥巴马不仅呼吁所有人 ...

  6. OpenStack 创建虚机过程简要汇总

    1. 总体流程 翻译自原文(英文):https://ilearnstack.com/2013/04/26/request-flow-for-provisioning-instance-in-opens ...

  7. 【转载】这样去写你的HTML

    昨天在 twitter 上说,怎么忍心把页面写得这么难用?是的,这个世界还有一群人等着我们创建出来的东西,可以让他们的生活能过得更容易呢.比如那些需要读屏软件的用户.作为一个前端,我们又怎么会忍心呢. ...

  8. php给app写接口进行接口的加密

    <?php/**inc解析接口客户端接口传输规则:1.用cmd参数(base64)来动态调用不同的接口,接口地址统一为 http://a.lovexpp.com2.将要传过来的参数组成一个数组, ...

  9. view之自定义控件

    转载自:http://blog.163.com/ppy2790@126/blog/static/103242241201382210910473/ 开发自定义控件的步骤: 1.了解View的工作原理  ...

  10. golang 反射应用(二)

    golang反射应用(二) package test import ( "reflect" "testing" ) //定义适配器 func TestRefle ...