Reputation: 839
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:
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.
Upvotes: 2
Views: 8803
Reputation: 101
I was facing same issue while using Gradle as build tool. In my case mongoRepository bean of module B was used in module A, so while starting up module A it was failing due to bean initialization failure.
I tried solution by adding @EntityScan and @ComponentScan with basepackage attribute but it was not worked.
Final solution was to add basePackages attribute in @EnableMongoRepositories in @Configuration class. As I was Autowiring mongorepository and that was failing.
Ex. @EnableMongoRepositories(basePackages = {"com.mycompany"})
Upvotes: 0
Reputation: 472
The module B is getting loaded first, then C and finally A.
The module B contains the bean HelloWorld which needs a bean injected, the bean MessagesImpl from module C.
So the MessagesImpl(module C) cannot be injected into HelloWorld(module B) because it has not been created yet, hence, it is never used and the context cannot be started.
The solution would be or change the dependencies, or move the beans to another module, like HelloWorld on module C and MessagesImpl on Module B.
Upvotes: 0
Reputation: 1214
Here what I do for my libraries:
@ComponentScan
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.my.library.MyLibraryConfiguration
@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.
Upvotes: 6