【问题标题】:Prohibit injection via access modifier禁止通过访问修饰符注入
【发布时间】:2017-10-13 12:51:37
【问题描述】:

考虑一个立面

public interface LoggingFacade {
    void log(String logMessage);
}

对应的bean

public class LoggingBean implements LoggingFacade {
    @Inject
    private LoggingService loggingService;

    @Override
    public void log(String logMessage) {
        loggingService.log(logMessage);
    }
}

public class LoggingService {
    public void log(String logMessage) {
        // some logic and logging
    }
}

它们都位于同一个包中。我希望每个程序员都调用外观而不是直接调用服务(在其他包中)。所以我尝试向LoggingService添加一个受保护的构造函数。

public class LoggingService {
    protected LoggingService() {
    }

    public void log(String logMessage) {
        // some logic and logging
    }
}

遗憾的是,这并不禁止在其他类中使用(注入)LoggingService。或者换句话说

public class MyClass {
    @Inject
    private LoggingService loggingService;

    public void foo() {
        loggingService.log("Hello");
    }
}

有效。你知道如何禁止使用LoggingService,所以每个用户都必须调用LoggingFacade吗?

【问题讨论】:

  • 你能不能不让日志服务不公开?
  • 您建议使用哪种修饰符?
  • 你想让LoggingService成为一个CDI bean吗? (如果是,为什么?)如果不是,您可以将课程设为私有(也可能是@Vetoed)。理由:您想禁止其他人使用它,那么为什么要首先公开它呢?它甚至和外观在同一个包中的事实让我认为它是外观的一个实现细节。
  • 只需从您不希望在包外部可见的类中删除 public 修饰符。
  • 如果我让LoggingService 包受保护,它仍然可以注入任何其他类。我希望 Logging Service 成为 CDI bean,因为我想将它注入我的 LoggingService。我不想把逻辑放在facadeBean 中,因为facade 应该没有逻辑,只是委托。我们目前采用的解决方案是添加一个带参数的包保护构造函数。这样你就不能在其他任何地方注入它。在 bean 中,我们通过 new 创建了对象。

标签: java cdi visibility code-injection


【解决方案1】:

只要您没有 Java 9 模块系统,就没有办法做到这一点。

使用 Java 9,您可以定义一个不导出 LoggingService 的单独模块。

【讨论】:

  • 使用 Jigsaw...我猜您使用的 IDE 不会警告您。我猜你会在编译时得到错误!?我不确定这有多有用。阴影很多。
  • 使用支持 Java 9 的 IDE,就像现在大多数情况一样,您不能使用未导出的类。就像在 IntelliJ 中一样 blog.jetbrains.com/idea/2017/09/java-9-and-intellij-idea
猜你喜欢
  • 2015-08-14
  • 2014-11-03
  • 2017-08-18
  • 2013-05-25
  • 2015-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-17
相关资源
最近更新 更多