理解Jakarta EE 8-CDI第1部分


软件开发人员的基本目的是编写以下代码:

  • 易于维护和测试。
  • 松散耦合。
  • 容易扩展。

构建分布式Java企业应用程序需要在跨各种应用程序层连接各种主流技术,通过一系列应用程序和业务服务将Web控制器与数据库后端绑定方面的深刻理解。这使得难以实现上面强调的要点,这使得开发人员要做他们最擅长的事情:编写代码是一个巨大的学习曲线。

ç ontext和d ependency我njection(CDI)是一种Java EE 6中(引进这样一种技术JSR 299),其目标编织与事务层Web层的帮助。

Jakarta EE 8 CDI规范版本是CDI 2.0,它是对CDI 1.2(JSR 346)的更新。

依赖注入 根据维基百科:

在软件工程中,依赖注入是 一种对象接收其依赖的其他对象的技术。这些其他 对象称为依赖项。在典型的“使用”关系中 ,接收对象称为客户端,而传递的(即 “注入”)对象称为服务。

依赖注入有助于消除对硬编码依赖(对象创建和实例化)的需求,从而使我们的应用程序松散耦合,可维护,可扩展且易于测试。使用CDI,依赖项解析是在运行时完成的。DI容器(注入器)负责注入依赖的bean。

那么,什么是CDI? CDI是一种类型安全的依赖项注入方法。在各种服务和功能中,它提供绑定到定义良好的上下文的有状态Bean的生命周期管理。这为开发人员提供了很大的灵活性,可以以松散耦合且类型安全的方式集成各种组件。

本文以教程格式讨论依赖项注入。它涵盖了CDI的某些功能,例如类型安全注释配置,替代方法等等。

CDI依赖注入 要使用CDI管理bean注入,我们将需要执行以下操作:

设置Bean存档。 Bean类必须存在于Bean归档文件中,才能被CDI容器发现。

要启用Bean归档,beans.xml必须存在于以下文件夹中,并将其bean-discovery-mode设置为all或annotated。如果Bean发现模式设置为none,则不再是Bean存档文件。

版本2.0的beans.xml文件的示例

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd "
    version="2.0" bean-discovery-mode="all">

</beans>
  • 在WAR文件中,放置您的beans.xml内部WEB-INF文件夹。
  • 在一个JAR文件中,将您beans.xml放置在该META-INF文件夹中。在Maven项目中,该文件必须存在于src/main/resources/META-INF目录中。 annotated如果指定了版本号(1.1或更高版本),则默认的Bean发现模式为,all否则为。这意味着所有Bean类都必须使用Bean定义注释进行注释,以便有资格进行Bean发现。

注意:该beans.xml文件可以是空文件。

现在,让我们看一下如何创建符合注入条件的bean的各种示例。本教程介绍了依赖注入,基础@Inject,@Produces和@Qualifiers。

行动中的CDI 为了理解CDI,我们必须在Java SE中引导CDI。即使JSR 299提供了实现我们自己的CDI容器的要求,我们仍将使用现有的JSR 299参考实现(RI)。在此示例中,我们使用JBoss Weld(JSR 299 CDI RI)。

我们包括weld-se-core对您的Maven项目的依赖。

<dependency>
    <groupId>org.jboss.weld.se</groupId>
    <artifactId>weld-se-core</artifactId>
    <version>${org.jboss.weld.se.core.version}</version>
</dependency>

哪里org.jboss.weld.se.core.version3.1.4.Final在写作的时候。

同样,我们也不希望容器发现Weld特定的bean,因此我们在上添加了以下排除项beans.xml

<scan>
    <exclude name="org.jboss.weld.**" />
</scan>

CDI中基本依赖注入的示例 在此示例中,我们将通过仅注入@Inject基本bean来介绍基本注入。

DefaultService.java

public class DefaultService {
    public void doWork() {
        System.out.println("Default Service work.");
    }
}

MainController.java

public class MainController {
    @Inject
    private DefaultService service;

    public void execute() {
        service.doWork();
    }
}

Main.java

public class Main {
    public static void main(String[] args) {
        SeContainer container = null;

        try {
            SeContainerInitializer containerInitializer = SeContainerInitializer.newInstance();
            container = containerInitializer.initialize();

            //Get bean via CDI
            MainController controller = container.select(MainController.class).get();
            controller.execute();
        } finally {
            if (container != null) {
                container.close();
            }
        }
    }
}

通过MainControllercontainerCDI容器中选择,可以在运行时以类型安全的方式解析Bean并将其注入。

您会注意到,DefaultService并且MainController尚未由任何合格的Bean批注进行批注,因此该Bean被限定为@Default限定符。另外,如果没有将限定符传递给SeContainer.select()方法,则将@Default假定该限定符。

当我们运行该Main程序时,Weld将把参数设置为,SeContainer而Weld成为进行注入的CDI容器。

输出:

2020年7月15日,上午5:33:51 org.jboss.weld.bootstrap.WeldStartup 信息:WELD-000900:3.1.4(最终) 警告:发生了非法的反射访问操作 警告:组织进行了非法的反射访问.jboss.weld.util.bytecode.ClassFileUtils $ 1(文件:/ C:/Users/buhake.sindi/.m2/repository/org/jboss/weld/weld-core-impl/3.1.4.Final/weld-core -impl-3.1.4.Final.jar)到方法java.lang.ClassLoader.defineClass(java.lang.String,byte [],int,int) 警告:请考虑将其报告给org.jboss.weld的维护者.util.bytecode.ClassFileUtils $ 1 警告:使用--illegal-access = warn启用警告进一步的非法反射访问操作 警告:在以后的发行版中,所有非法访问操作都将被拒绝。 2020年7月15日,上午5:33:52 org.jboss.weld.bootstrap.WeldStartup startContainer 信息:WELD-000101:事务服务不可用。@Inject UserTransaction的注入不可用。事务性观察者将被同步调用。 2020年7月15日上午5:33:53 org.jboss.weld.environment.se.WeldContainer fireContainerInitializedEvent INFO:WELD-ENV-002003:Weld SE容器0b2888f8-0582-4b76-a2db-2c04514757a4初始化了 默认服务工作。 2020年7月15日上午5:33:53 org.jboss.weld.environment.se.WeldContainer关闭 信息:WELD-ENV-002001:焊接SE容器0b2888f8-0582-4b76-a2db-2c04514757a4已关闭

我们可以看到它Default Service work.是在控制台上输出的。

该示例的完整源代码可以在GitHub源代码树上找到。

让我们暂停片刻。我们将进行与由CDI框架以及在规格本其它特征提供DI喷射的其他各种方式(例如events,interceptors等)。


原文链接:http://codingdict.com