Issue
I am struggling with a problem and I don't know how to solve it.
This is the structure of my project using Maven :
myProject:
- moduleA <-- has dependencies on moduleB and moduleC
- moduleB <-- has no dependency
- moduleC <-- has dependency on moduleB
I wrote two interfaces in moduleB, one of them is implemented in moduleB, the other one is implemented in moduleC.
Greeting interface :
public interface Greeting {
WelcomeMessage greet();
}
Its implementation written on moduleB :
@Component
public class HelloWorld implements Greeting {
private final Messages messages;
public HelloWorld(Messages messages) {
this.messages = messages;
}
@Override
public WelcomeMessage greet() {
return messages.getWelcomeMessage();
}
}
Messages interface:
public interface Messages {
WelcomeMessage getWelcomeMessage();
}
Its implementation written on moduleC :
@Component
public class MessagesImpl implements Messages {
private final Mapper mapper;
private final MessageRepository messageRepository;
public MessagesImpl(Mapper mapper, MessageRepository messageRepository) {
this.mapper = mapper;
this.messageRepository = messageRepository;
}
@Override
public WelcomeMessage getWelcomeMessage() {
// do something with repository and mapper
}
}
My problem is Spring does not seem to use the implementation of Messages from moduleC, this error shows when I start the application :
**required a bean of type 'fr.mypackage.core.spi.Messages' that could not be found**
Also IntelliJ keeps telling me MessagesImpl is never used.
Solution
Here what I do for my libraries:
- Every library has a configuration class at top package level with
@ComponentScan
- It can be empty or have additional beans if necessary
- Then, either the library is made an autoconfiguration with a file META-INF/spring.factories in src/main/resouces with the content:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.my.library.MyLibraryConfiguration
- Or I manually import the configuration class in my main application configuration class with
@Import(com.example.my.library.MyLibraryConfiguration)
For a module, I recommend the autoconfiguration approach. You can @ComponentScan
from the main application the packages of your library, but I don't recommend that, it give you less control and can be messy.
Answered By - Nyamiou The Galeanthrope
Answer Checked By - Terry (JavaFixing Volunteer)