【问题标题】:Does CDI work for regular Java application?CDI 是否适用于常规 Java 应用程序?
【发布时间】:2014-10-13 07:58:59
【问题描述】:

我有三个类的简单 Maven 项目。在我的META-INF 中,我有空的beans.xml。每次我运行我的Main.java 时,我都会得到一个NullPointerException

Exception in thread "main" java.lang.NullPointerException
at hom.World.helloWorld(World.java:12)
at hom.Main.main(Main.java:6)

我想要完成的工作是否超出了 CDI 的范围?

Hello.java

package hom;
import javax.enterprise.inject.Default;

@Default
public class Hello {
   public String hello() {
      return "Hello ";
   }
}

世界.java

package hom;
import javax.enterprise.inject.Default;
import javax.inject.Inject;

@Default
public class World {
   @Inject
   Hello hello;

   public String helloWorld() {
      return hello.hello() + "World!";
   }
}

Main.java

package hom;
public class Main {
   public static void main(String[] args) {
      World helloWorld = new World();
      System.out.println(helloWord.helloWorld());
   }
}

【问题讨论】:

  • 您仍然需要某种容器。 Spring 是一个很好的默认选择,尤其是使用 Spring Boot。
  • 您可以使用 Weld 将 CDI 用于桌面应用程序,请参阅:aprogrammersguidetothegalaxy.blogspot.co.il/2010/08/…
  • @chrylis 如果我想将它用作我的 Web 应用程序的实用程序 jar 怎么办?我还需要容器吗?
  • 这是场注入是一种糟糕模式的众多原因之一。如果你改用构造函数注入,你仍然可以将@Inject放在构造函数上,但你可以通过专门传入依赖项来轻松地在容器外使用它。

标签: java cdi


【解决方案1】:

以下示例适用于 CDI 2。

<dependency>
    <groupId>org.jboss.weld.se</groupId>
    <artifactId>weld-se-core</artifactId>
    <version>3.1.2.Final</version>
</dependency>

依赖是一样的。

package com.zetcode;

import com.zetcode.provider.HelloMessageProvider;
import com.zetcode.renderer.ConsoleMessageRenderer;
import com.zetcode.renderer.MessageRenderer;

import javax.enterprise.inject.se.SeContainer;
import javax.enterprise.inject.se.SeContainerInitializer;

public class CdiSimple {

    public static void main(String[] args) {

        SeContainerInitializer initializer = SeContainerInitializer.newInstance();

        try (SeContainer container = initializer.disableDiscovery()
                .addBeanClasses(HelloMessageProvider.class, ConsoleMessageRenderer.class).initialize()) {

            MessageRenderer messageRenderer = container.select(ConsoleMessageRenderer.class).get();
            messageRenderer.render();
        }
    }
}

我们使用SeContainerInitializerSeContainer 在Java SE 上设置CDI。

package com.zetcode.provider;

public interface MessageProvider {

    String getMessage();
}

这是MessageProvider

package com.zetcode.provider;

public class HelloMessageProvider implements MessageProvider {

    public String getMessage() {

        return "Hello there";
    }
}

这是HelloMessageProvider

package com.zetcode.renderer;

public interface MessageRenderer {

    void render();
}

这是MessageRenderer

package com.zetcode.renderer;

import com.zetcode.provider.MessageProvider;

import javax.inject.Inject;

public class ConsoleMessageRenderer implements MessageRenderer {

    @Inject
    private MessageProvider messageProvider;

    public void render() {

        var message = messageProvider.getMessage();

        System.out.println(message);
    }
}

最后,这是ConsoleMessageRenderer

【讨论】:

    【解决方案2】:

    可以在独立应用程序中使用 CDI。

    Weld weld = new Weld();
    WeldContainer container = weld.initialize();
    World helloWorld = container.instance().select(World.class).get();
    System.out.println(helloWorld.helloWorld());
    weld.shutdown();
    

    您还需要weld-se 依赖项。

    <dependency>
        <groupId>org.jboss.weld.se</groupId>
        <artifactId>weld-se-core</artifactId>
        <version>2.2.4.Final</version>
    </dependency>
    

    另请参阅Weld documentation 关于该主题。

    【讨论】:

    猜你喜欢
    • 2023-03-03
    • 1970-01-01
    • 2012-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 2014-11-08
    相关资源
    最近更新 更多