I have recently updated my project to spring boot v 3.0.6 (from 2.2.5) and Java version 17 (from 11). My approach is to register the controller not by using class-level annotations (like @Controller or @RestController) but instead by using the method shown below.
Configuration class:
@Configuration
class CampaignConfig {
@Bean
CampaignController campaignController(CampaignRepository campaignRepository,
MongoOperations mongoOperations, MongoTemplate mongoTemplate,
ExternalApiFacade externalApiFacade) {
final var campaignMapper = new CampaignMapperImpl();
final var campaignWriterService = campaignWriterService(
campaignRepository, mongoTemplate, externalApiFacade,
campaignMapper);
final var campaignReaderService = new CampaignReaderServiceImpl(mongoOperations,
campaignMapper);
return new CampaignController(campaignWriterService, campaignReaderService);
}
}
Controller class:
@AllArgsConstructor
@RequestMapping("/panel/campaign")
class CampaignController {
private CampaignReaderService campaignReaderService;
@GetMapping
@ResponseBody
public List<CampaignRestDto> getCampaign(
@RequestParam(required = false) CampaignType campaignType,
@RequestParam(required = false) Set<CampaignStatus> campaignStatus,
@RequestParam(required = false) Long campaignId,
@RequestParam(required = false) Long oddsProviderId) {
final var searchCriteria = CampaignSearchCriteria.builder()
.campaignType(campaignType)
.campaignStatuses(campaignStatus)
.campaignId(campaignId)
.oddsProviderId(oddsProviderId)
.build();
return campaignReaderService.getCampaigns(searchCriteria);
}
}
In spring boot 2 this approach works like charm. CampaignController is registered as a bean and starting my app locally on port 8080 I can access the endpoint http://localhost:8080/panel/campaign. In spring boot 3 this approach doesn't work. Bean is registered but the endpoint http://localhost:8080/panel/campaign is not accessible.
To test it further I added a logging
logging.level.org.springframework.web=TRACE
and registered a dummy controller with class-level annotation
@RestController
public class TestController {
@GetMapping("/test")
public String getTest(){
return "test";
}
}
When I run the app I can see in the logs:
2023-04-26T11:28:31.102+02:00 TRACE 4552 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping :
p.c.a.a.s.p.c.r.TestController:
{GET [/test]}: getTest()
but no logs related to CampaignController.
Is this a bug in spring boot 3, or this way of creating controllers is no longer supported, or am I missing something?
Yes Springframework 6 (implicit in Springboot 3) requires controllers to be annotated with @Controller (so also @RestController) to be detected as a controller.