I am new to Spring Boot. As I understand how constructor injection works then I can't tell why HelloController
works - index method is not a constructor so where/why cat object instance is created? Would be glad to get some documentation or articles about it.
HelloController.java
@RestController
public class HelloController {
@GetMapping("/{name}")
public String index(@PathVariable("name") String name, Cat cat){
cat.setName(name);
return "<b>Hello " + cat.getName() + "</b>";
}
}
Cat.java
@Component
public class Cat {
@Getter @Setter
private String name;
public Cat(){
System.out.println("Created new Cat!");
}
}
This is an interesting question - only because of the way you have put it. By injection, do you mean creation of a singleton class (You have Cat
marked as @Component
)? Well to answer this, I added something extra to your print
statement:
public Cat(){
System.out.println("Created new Cat! with hasCode: " + hashCode());
}
You see, the hashCode
should not change for the same object. The results are not very surprising:
Created new Cat! with hasCode: 362563829
Created new Cat! with hasCode: 782885695
The first line was printed when the application was started. That is expected as the bean is created with a scope of singleton
and the process completes before the application is completely loaded. The second output comes when I make a request to the endpoint in which case, Spring creates an instance of Cat
and passes it as an argument to the @GetMapping
. You get as many objects of Cat
as your requests.
Along the same lines, if i remove @Component
from Cat
, the first line does not show up.
Moving along, I made another change to the RestController
class:
@RestController
public class HelloController {
@Autowired
private Cat myCat;
@GetMapping("/{name}")
public String index(@PathVariable("name") String name, Cat cat){
cat.setName(name);
System.out.println("Hello " + myCat.hashCode());
return "Hello " + cat.getName() + "The age is: " + cat.getAge();
}
}
Here is the result of running this application:
What it shows is that the cat passed on to the controller method is not same as the one that was managed by Spring container.
N.B.: I have not really come across any official documentation statinng above findings. Would be very happy to see one though