Search code examples
javacdivisibilitycode-injection

Prohibit injection via access modifier


Consider a facade

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

with corresponding bean

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

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

with

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

They all lie in the same package. I want every programmer to call the facade and not to call the service directly (in other packages). So I tried to add a protected constructor to LoggingService.

public class LoggingService {
    protected LoggingService() {
    }

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

Sadly, this does not prohibit the usage (injection) of LoggingService in other classes. Or in other words

public class MyClass {
    @Inject
    private LoggingService loggingService;

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

works. Do you have any idea how to prohibit the usage of LoggingService so every user has to call the LoggingFacade?


Solution

  • There is no way to do this as long as you don't have Java 9 module system.

    With Java 9 you could define a separate module that does not export the LoggingService.