Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inject service in controller's method?

I have problem with injecting service in controller's method. I have following service:

@Service
@RequiredArgsConstructor
public class CreateFranchiseUseCase {
    private final FranchiseService franchiseService;
    private final UserService userService;
    private final ACLEntryService aclEntryService;
    private final FranchiseDTOMapper franchiseDTOMapper;

    public Franchise execute(CreateFranchiseDTO dto) {
        // ...
    }
}

And then in Controller:

@RestController
@RequiredArgsConstructor
public class FranchiseController {

    // ...
    
    @PostMapping("/api/franchises")
    public ResponseEntity<Object> createFranchise(CreateFranchiseDTO dto, CreateFranchiseUseCase useCase) {
        Frachise franchise = useCase.execute(dto);
        // ...
    }
}

When I call this endpoint I get NullPointerException. The exception occurs in execute method and debugging the method I discovered that all attributes: franchiseService, userService, aclEntryService and franchiseDTOMapper are NULL.

All classes: FranchiseService, UserService and ACLEntryService are annotated with @Service annotation. And FranchiseDTOMapper is annotated with @Mapper(componentModel = "spring")

Does Spring support Method Injection? Alternativly is there any way I can request instance of CreateFranchiseUseCase class inside createFranchise() method like so:

@PostMapping("/api/franchises")
public ResponseEntity<Object> createFranchise(CreateFranchiseDTO dto) {
    CreateFranchiseUseCase useCase = container.get(CreateFranchiseUseCase.class) // <-- something like this
    Frachise franchise = useCase.execute(dto);
    // ...
}
like image 527
clzola Avatar asked Jan 25 '26 12:01

clzola


2 Answers

Does Spring support Method Injection?

No. Receivable objects by arguments is listed here:

  • https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-reference/web.html#mvc-ann-arguments

You can use ApplicatonContext#getBean():

    @Autowired
    private ApplicationContext context;

    @PostMapping("/api/franchises")
    public ResponseEntity<Object> createFranchise(CreateFranchiseDTO dto) {
        reateFranchiseUseCase useCase = context.getBean(CreateFranchiseUseCase.class);
        // ...
    }

If CreateFranchiseUseCase object instanciation by each request is required, you need to add @Scope(WebApplicationContext.SCOPE_REQUEST):

@Service
@Scope(WebApplicationContext.SCOPE_REQUEST)
public class CreateFranchiseUseCase {
like image 119
DEWA Kazuyuki - 出羽和之 Avatar answered Jan 27 '26 01:01

DEWA Kazuyuki - 出羽和之


As far as I know it is not possible to let Spring inject Objects into methods.
Instead you can let Spring inject the object through the constructor of your controller.

This would lead to something like this:

@RestController
public class FranchiseController {

    private final CreateFranchiseUseCase createFranchiseUseCase;

    public FranchiseController(CreateFranchiseUseCase createFranchiseUseCase) {
        this.createFranchiseUseCase = createFranchiseUseCase;
    }

    @PostMapping("/api/franchises")
    public ResponseEntity<Object> createFranchise(CreateFranchiseDTO dto) {
        Frachise franchise = createFranchiseUseCase.execute(dto);
        // ...
    }
}

This should also work even when you use Lombok to create your constructor.

like image 23
Jan Schmitz Avatar answered Jan 27 '26 02:01

Jan Schmitz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!