0

I have a spring-boot project with 3 maven modules in it: producer, consumer and api.

  • Api contains an interface.
  • Consumer depends on api and contains the main method and @SpringBootApplication. The class is also in a package that prefixes all the other classes in the other two jars so Component Scan could find everything
  • Producer depends on api and contains an implementation of the api interface annotated with @Service

In Consumer, i'm trying to get the producer to be injected in the constructor but without referencing the concrete implementation, just the interface. The consumer maven module doesn't even depend on the producer module. This is similar to the way you create applications in OSGi where concrete provider implementations are supposed to be hidden from their consumers.

My problem is that the producer is not being injected. It is not being instantiated or even its class loaded since nobody is referencing it. How can I accomplish this in spring (boot) while keeping the strong encapsulation requirement of consumers not being aware of concrete producers?

When I run the app I get UnsatisfiedDependencyException since there's not producer instantiated to be injected

This is a simplified representation of my code

package com.foo.api
public interface Doer {
}
===== different jar =====
package com.foo
@SpringBootApplication
public class Consumer {
  public static void main(String[] args) {
    SpringApplication.run(Consumer.class, args);
  }

  @Autowire
  public Consumer(Doer someDoer) {
  }
}
===== different jar ======
package com.foo.services
@Service
public class Producer implements Doer {

}
Hilikus
  • 9,954
  • 14
  • 65
  • 118

1 Answers1

1

You need to add the Producer module as a dependency of the Consumer module, otherwise maven is not packaging it with the spring boot application - hence it is not available at runtime (the jar is missing).
In order to keep the good separation you defined, make sure to set the dependency's scope to runtime. This means it is not required in compile time but maven knows it needs to be in runtime so it packages the dependency with the application.

For example, add the following the consumer's pom.xml (after setting the correct values...):

<dependency>
  <groupId>com.foo.services</groupId>
  <artifactId>producer</artifactId>
  <version>1.2.3</version>
  <scope>runtime</scope>
</dependency>
yinon
  • 1,418
  • 11
  • 14