Container and Injection in Java

时间:2023-11-11 23:44:32

一、Container

1、为什么使用Container

通常,瘦客户端多层应用程序很难编写,因为它们涉及处理事务和状态管理、多线程、资源池和其他复杂的低级细节的复杂代码行。基于组件和独立于平台的JavaEE体系结构使应用程序易于编写,因为业务逻辑被组织成可重用的组件。此外,JavaEE服务器以容器的形式为每种组件类型提供底层服务。因为您不需要自己开发这些服务,所以您可以*地集中精力解决手头的业务问题。

2、Container Services

容器是组件与支持组件的低级平台特定功能之间的接口。在执行该组件之前,必须将Web、企业bean或应用程序客户端组件组装到JavaEE模块中并部署到其容器中。

组装过程包括为JavaEE应用程序中的每个组件和JavaEE应用程序本身指定容器设置。容器设置自定义JavaEE服务器提供的底层支持,包括安全性、事务管理、Java命名和目录接口(JNDI)API查找和远程连接等服务。以下是一些亮点。

  • JavaEE安全模型允许您配置Web组件或企业bean,以便系统资源仅由授权用户访问。

  • JavaEE事务模型允许您指定组成单个事务的方法之间的关系,以便将一个事务中的所有方法视为一个单元。

  • JNDI查找服务为企业中的多个命名和目录服务提供了统一的接口,以便应用程序组件可以访问这些服务。

  • JavaEE远程连接模型管理客户端和企业bean之间的低级通信。创建企业bean之后,客户端将调用方法,就像在同一虚拟机中一样。

因为JavaEE体系结构提供了可配置的服务,所以同一应用程序中的组件可以根据部署的位置而有所不同。例如,企业bean可以具有安全设置,允许它在一个生产环境中访问数据库数据,在另一个生产环境中访问另一个级别的数据库。

容器还管理不可配置的服务,如企业bean和servlet生命周期、数据库连接资源池、数据持久性和对JavaEE平台API的访问

3、Container Types

Container and Injection in Java

服务器和容器如下:

  • JavaEE服务器:JavaEE产品的运行时部分。JavaEE服务器提供EJB和Web容器。

  • EJB容器:为JavaEE应用程序管理企业bean的执行。企业bean及其容器运行在JavaEE服务器上。

  • Web容器:管理用于JavaEE应用程序的Web页面、servlet和一些EJB组件的执行。Web组件及其容器在JavaEE服务器上运行。

  • 应用程序客户端容器:管理应用程序客户端组件的执行。应用程序客户端及其容器在客户端上运行。

  • applet容器:管理applet的执行。由Web浏览器和一起运行在客户端上的Java插件组成。

二、Injection

1、为什么使用Injection

JavaEE提供了注入机制,使对象能够获得对资源和其他依赖项的引用,而不必直接实例化它们。您可以通过用标记字段为注入点的注释之一来修饰字段或方法来声明类中所需的资源和其他依赖项。然后容器在运行时提供所需的实例。注入简化了代码,并将其与其依赖关系的实现分离。

2、资源注入

资源注入使您能够将JNDI命名空间中的任何可用资源注入任何容器托管对象,例如servlet、企业bean或托管bean。例如,可以使用资源注入JNDI命名空间中可用的数据源、连接器或自定义资源。

用于引用注入实例的类型通常是一个接口,它将代码与资源的实现分离开来。

例如,以下代码注入一个数据源对象,该对象提供与GlassFishServer附带的默认Apache Derby数据库的连接:

public class MyServlet extends HttpServlet {
    @Resource(name="java:comp/DefaultDataSource")
    private javax.sql.DataSource dsc;
    ...
}

除了前面示例中的基于字段的注入之外,还可以使用基于方法的注入来注入资源:

public class MyServlet extends HttpServlet {
    private javax.sql.DataSource dsc;
    ...
    @Resource(name="java:comp/DefaultDataSource")
    public void setDsc(java.sql.DataSource ds) {
        dsc = ds;
    }
}

要使用基于方法的注入,setter方法必须遵循JavaBeans对属性名称的约定:方法名称必须以set,有一个void返回类型,并且只有一个参数。

3、依赖注入

依赖注入使您能够将常规Java类转换为托管对象,并将它们注入到任何其他托管对象中。使用依赖项注入,代码可以声明对任何托管对象的依赖关系。容器在运行时在注入点自动提供这些依赖项的实例,并为您管理这些实例的生命周期。

JavaEE中的依赖注入定义了作用域,这些作用域确定容器实例化和注入的对象的生命周期。例如,只需要响应单个客户端请求(例如货币转换器)的托管对象的作用域与在会话中处理多个客户端请求(例如购物车)所需的托管对象不同。

您可以定义托管对象(也称为托管bean),以后可以通过将作用域分配给常规类来注入这些对象:

@javax.enterprise.context.RequestScoped
public class CurrencyConverter { ... }

使用javax.inject.Inject注解注入托管bean;例如:

public class MyServlet extends HttpServlet {
    @Inject CurrencyConverter cc;
    ...
}

与资源注入不同,依赖注入是类型,因为它按类型进行解析。要将代码与托管bean的实现分离,可以使用接口类型引用注入的实例,并让托管bean实现该接口。

4、资源注入与依赖注入的主要区别

表 资源注入和依赖注入之间的差异

Injection Mechanism Can Inject JNDI Resources Directly Can Inject Regular Classes Directly Resolves By Typesafe
Resource Injection Yes No Resource name No
Dependency Injection No Yes Type Yes