I am wondering what the best place would be for a Spring Boot app to register additional beans. I have a Main class that is annotated with @SpringBootApplication
It depends on where the main class is located which has generally @SpringBootApplication annotations. You can annotate this main class with @ComponentScan(basePackageClasses = HelloWorld.class). Here HelloWorld has had definitions annotated with @Beans and the class is annotated with @Configurations.
Spring container will scan all the sub-packages of the class specified in @ComponentScan arguments. You can also give wild card entries for basePackageClasses argument instead of class name as specified above. E.g.
@SpringBootApplication
@ComponentScan(basePackageClasses = HelloWorld.class)
public class DemoApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class);
}
}
Bean Class:
@Configuration
public class HelloWorld {
@Bean
public TweetUserSevice tweetUserSevice() {
return new TweetUserSeviceImpl();
}
}
Another approach:
Generally in big projects, we will have multiple spring config classes containing bean definitions. We can avoid worrying about that all the bean class should be in sub-package of main class. What we can do is that we can have a single master spring config class(but make sure this master spring config class is under sub-package of main class so that @SpringBootApplication annotations automatically detects the master config) and import all the other bean classes.
I have 2 bean classes (TweetBeansConfig, TweetSystemHealthBeansConfig) in the package com.ronak.tweet (This package is not sub-package where main class exists). I have one master spring config class (TweetMasterSpringConfig) and this class resides in package which is sub-package where my main class resides.
package com.ronak.tweet.beans;
@Configuration
@Order(value=1)
@Import({
TweetBeansConfig.class,
TweetSystemHealthBeansConfig.class
})
public class TweetMasterSpringConfig {
public TweetMasterSpringConfig() {
System.out.println("Initilaizing master spring config");
}
}
package com.ronak.beans;
@Configuration
public class TweetBeansConfig {
@Bean
{
//
}
}
package com.ronak.beans;
@Configuration
public class TweetSystemHealthBeansConfig {
@Bean
{
//
}
}
Main class
package com.ronak.tweet;
@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {
/**This is for registing REST layer for Jersey which implements jaxb. It will register all the classes which is in the pacakage com.ronak.tweet.rest. You can add comma separated package names too.
@Bean
ResourceConfig resourceConfig() {
return new ResourceConfig().packages("com.ronak.tweet.rest");
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class);
}
}