Search code examples
javaspringspring-bootservicecontroller

How is the Service recognized in the controller


I have a controller that has a service in Spring boot.

The Controller is like this :

@Controller
@SessionAttributes("name")
public class TodoController {

    private TodoService todoService;

    public TodoController(TodoService todoService) {
        super();
        this.todoService = todoService;
    }

    @RequestMapping("list-todos")
    public String showTodos(ModelMap model){
        List<Todo> todos = todoService.findByUsername("Gerald");
        model.addAttribute("todos", todos);
        return "todoList";
    }

And the service like this

@Service
public class TodoService {
    private static List<Todo> todos = new ArrayList<>();

    static {
        Todo todo1 = new Todo(1, "Gerald", "Learn Java", LocalDate.now().plusYears(1), false);
        Todo todo2 = new Todo(2, "Gerald", "Learn Python", LocalDate.now().plusYears(2), false);
        Todo todo3 = new Todo(2, "Gerald", "Learn OCaml", LocalDate.now().plusYears(3), false);
        Todo todo4 = new Todo(2, "Gerald", "Learn Cooking", LocalDate.now().plusYears(4), false);
        System.out.println(todo1);

        todos.add(new Todo(1, "Gerald", "Learn Java", LocalDate.now().plusYears(1), false));
        todos.add(new Todo(2, "Gerald", "Learn Python", LocalDate.now().plusYears(2), false));
        todos.add(new Todo(3, "Gerald", "Learn Handstand", LocalDate.now().plusYears(3), false));
        todos.add(new Todo(4, "Gerald", "Learn Cooking", LocalDate.now().plusYears(4), false));
    }

    public List<Todo> findByUsername(String name){
        return todos;
    }

    public void addTodo(Todo todo){
        todos.add(todo);
    }


}

The code works properly if in Controller I have

@RequestMapping("list-todos")
public String showTodos(ModelMap model){
    List<Todo> todos = this.todoService.findByUsername("Gerald");
    model.addAttribute("todos", todos);
    return "todoList";
}

Why does it also work instead I have in there:

    List<Todo> todos = todoService.findByUsername("Gerald");

In other words, how does the controller know what todoService is in that context when there is no this before ?


Solution

  • JLS, §6.5.6.1: Simple Type Names, states that:

    If an expression name consists of a single Identifier, then there must be exactly one declaration denoting either a local variable, formal parameter, exception parameter, or field in scope at the point at which the identifier occurs. ...

    Thus, we can access instance fields without this (as long as there is no name clash with a local variable or parameter, then this is needed to distinguish between the local variable/parameter and the instance field).