java - 访问注入(inject)的属性会导致 NullPointerException

标签 java cdi quarkus

这是我第一次与 Quarkus 和 CDI 合作,我认为我弄错了。

在我的应用程序中,用户可以下载一些文件。我想控制同时下载的文件数量。我想我可以通过创建一个带有 @ApplicationScoped 注释的 bean,在启动时强制实例化,然后在我需要知道当前正在下载多少文件的任何地方注入(inject)它来做到这一点。

这就是我设法做到的:

@ApplicationScoped
public class DownloadState {
    private int downloadingFiles;

    void startup(@Observes StartupEvent event) {
        setDownloadingFiles(0);
        System.out.println("downloading files: " + downloadingFiles);
    }

    public int getDownloadingFiles() {
        return downloadingFiles;
    }

    public void setDownloadingFiles(int downloadingFiles) {
        this.downloadingFiles = downloadingFiles;
    }

    public void incrementDownloadingFiles() {
        downloadingFiles++;
    }

    public void decrementDownloadingFiles() {
        downloadingFiles--;
    }
}

这样做我可以在启动时看到日志显示“下载文件:0”,所以我知道该类已被实例化。

我尝试在这里访问下载文件的数量:

public class Downloader {
    private static final Logger LOG = Logger.getLogger(Downloader.class);

    @Inject
    DownloadState downloadState;

    private Dotenv dotenv = Dotenv.configure()
        .directory("../")
        .filename(".env.local")
        .load();

    private String fileName = dotenv.get("DOWNLOAD_PATH");
    private String url;

    public Downloader(String url, String fileName) {
        this.url = url;
        this.fileName += fileName;
    }

    public void downloadProduct() {

        LOG.info("Downloading Files: " + downloadState.getDownloadingFiles());
        //...
    }
}

每当调用 downloadProduct 时,都会在行上抛出 NullPointerException LOG.info("Downloading Files: "+ downloadState.getDownloadingFiles());

我对 CDI 的理解完全错误吗?非常感谢任何帮助,提前谢谢您。

最佳答案

我假设您直接调用 Downloader 构造函数 - 在这种情况下,实际上不会发生注入(inject),并且您的 downloadState 将为 null。依赖注入(inject)具有“传染性”——你必须在任何地方使用它。

就您而言,我可能只是将 Downloader 也设置为 @ApplicationScoped,将其注入(inject)到您使用的任何地方,并可能移动 urlfileName 参数从构造函数传递给 downloadProduct。实际上,downloadingFiles 的数量也可能在 Downloader 中。 (另请注意,它可以从多个线程访问 - 因此我可能会使用 AtomicIntegerdownloadingFiles。)

总而言之,是这样的:

@ApplicationScoped
public class Downloader {
    private static final Logger LOG = Logger.getLogger(Downloader.class);

    private final AtomicInteger downloadingFiles = new AtomicInteger(0);

    private final String downloadPath = Dotenv.configure()
        .directory("../")
        .filename(".env.local")
        .load()
        .get("DOWNLOAD_PATH");

    public void downloadProduct(String url, String fileName) {
        String path = downloadPath + fileName;

        int current = downloadingFiles.incrementAndGet();
        LOG.info("Downloading Files: " + current);
        //...
    }
}

关于java - 访问注入(inject)的属性会导致 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68588874/

相关文章:

JFrame的Java Swing最大化按钮消失

java - 在reactor项目中运行Maven目标而不执行 "mvn install"

java - 在 Wildfly 的单例中注入(inject) @RequestScoped 变量

java - 如何在 Java Jersey 中使用 CDI 事件?

asynchronous - REST 端点 : Async execution without return value

kotlin - Quarkus Vert.x 示例

java - 对对象数组调用 setter

java - 使用 Apache Lucene 7.1.0 的 JapaneseTokenizer 时出现 NoClassDefFoundError

java - 是否可以使用 CDI 注入(inject) EJB 实现而不是其接口(interface)?

java - 对于在镜像运行时初始化或重新初始化的类,镜像堆中不允许有实例 : sun. security.provider.NativePRNG