1

I'm working on a spring project from our customer.

Below is the code for controller

@Log4j2
@RestController
@AllArgsConstructor
@RequestMapping(path = "/api/theapi")
@Api(value = "Description for the API")
public class TheAPIController {
private final ModelMapper modelMapper;
private final ObjectMapper objectMapper;
private final TheDemoService demoService;
...other code for controller
}

Below is the code for Service:

@Service
public class TheDemoService{ ... }

I was so surprise about 2 things:

Question 1: Why we need to use @AllArgsConstructor from project Lombok?

As per my understanding, Spring provide @RestController that Spring runtime container will initialize an Instance for our Controller. So that, having a constructor for our Controller seems like an invalid approach for using Spring Inversion of Control, is this correct?

Question 2. Because of using @AllArgsConstructor, somehow, the instance for demoService is to be injected

But again, I surprise because the code of Controller does not have @Autowired in combine with demoService.

In the actual code, there is no @Autowired for "private final TheDemoService demoService".

Hence, I could think of a possibility there, is that because of Lombok's @AllArgsConstructor would inject an instance of our TheDemoService via a constructor of

TheAPIController, I could not reason anything about this logic.

datnt
  • 372
  • 2
  • 15

1 Answers1

3
  1. It's Invalid approach, no need for defining constructor for RestController

  2. It's implicitly auto wiring the service

if a class, which is configured as a Spring bean, has only one constructor, the Autowired annotation can be omitted and Spring will use that constructor and inject all necessary dependencies.

To sum up @AllArgsConstructor can/should be removed

Ori Marko
  • 56,308
  • 23
  • 131
  • 233
  • Thank you for your feedback. In case we remove @ AllArgsConstructor, then we should use @ Autowire to inject our service, right? By the way, can you provide more reasoning related to "It's Invalid approach". From my perspective, I agree that it's invalid, just want to have more concrete technical artifact about that. Thanks. – datnt Aug 21 '19 at 10:48
  • 1
    @datnt 1. You **don't need** to add Autowired, but you **can**, to make autowiring obvious 2. spring will handle bean creation so no need to allow creating RestController instance outside Spring – Ori Marko Aug 21 '19 at 10:57
  • I just want to add an update to provide more information for latter readers. Following the code in my question, if we remove annotation @AllArgsConstructor. We have to remove "final" as well. E.g: private final ModelMapper modelMapper; BECOME --> private ModelMapper modelMapper; – datnt Aug 26 '19 at 08:32
  • @ user7294900 Sorry for response this late, I do not have any spare time during recent weeks. So, here is my update. I tried to remove @AllArgsConstructor, also remove "final", i.e, the bean injection is like this, e.g: private TheDemoService demoService; Now, spring project is able to run without any error, i.e: mvn spring-boot:run But when, I send request (i.e HTTP GET) to this controller, I got NullPointerException because demoService is null – datnt Sep 03 '19 at 10:52
  • Then, I inserted Autowire, as: @ Autowire private TheDemoService demoService; It works fine. I think, if we remove @ AllArgsConstructor, we must use @ Autowire with bean-injection in order for it to work. – datnt Sep 03 '19 at 10:53