0

I have a doubt regarding dependency injection,Suppose my controller ,service,dao all are singleton so usually when we create the controller we inject the service as a instance variable of that class, but according to the singleton pattern if our controller is stateless then only we would not face any concurrency issue but here We are declaring the service dependency so it should not be stateless so we have to take care of synchronization?

Please clear this doubt as I am beginner so I hope its natural to have this doubt in mind,I don't know if I am thinking totally wrong.Please help.

Beer Gupta
  • 67
  • 9
  • What synchronization do you imagine that you need? – OrangeDog Sep 13 '16 at 20:44
  • I just want to know that if I am injection service bean in controller class which is singleton in nature so by doing this am I making controller as Stateful in nature? if I am doing so am I not doing any thing wrong because everywhere its mentioned that any singleton bean should be stateless to prevent concurrency. – Beer Gupta Sep 13 '16 at 20:47
  • why do you think service should not be stateless? All singleton beans should be stateless (thread safe) – mokarakaya Sep 13 '16 at 21:14
  • yes you are right ,all the singleton bean should be stateless ,if not then different thread will share the same data and causes issues. I found the clear memory model and its good to learn about jvm memory model and by learning this I could do better design .Thanks :) – Beer Gupta Sep 13 '16 at 22:10

3 Answers3

1

All beans in Spring are Singleton by default. This includes any @Controller, @Service, @Repository and others, as well as any xml defined bean.

You could read this and this

From Java basic variable tutorial:

Local Variables Similar to how an object stores its state in fields, a method will often store its temporary state in local variables. The syntax for declaring a local variable is similar to declaring a field (for example, int count = 0;). There is no special keyword designating a variable as local; that determination comes entirely from the location in which the variable is declared — which is between the opening and closing braces of a method. As such, local variables are only visible to the methods in which they are declared; they are not accessible from the rest of the class.

Community
  • 1
  • 1
jlumietu
  • 6,234
  • 3
  • 22
  • 31
  • thank but as far I understand you mean when my controller is autowring the service bean it not hold any state only when service is also stateless so that multiple request would just share the local member of the class which reside in the stack of different requested thread – Beer Gupta Sep 13 '16 at 21:04
  • What do you mean when you say "the local member of the class" ? Do you intend your service (or any other component) to have any statefull innner property ? – jlumietu Sep 13 '16 at 21:08
  • sorry my mistake not local member of the class ,I meant method of the class which are public in nature and their local variables – Beer Gupta Sep 13 '16 at 21:11
  • Any local variable in a method class is not shared between more than one executions of the method, nevermind if each execution is done at the same time from different threads – jlumietu Sep 13 '16 at 21:15
  • " Any local variable in a method class is not shared between more than one executions of the method, " could you please explain it ,I want to understand the clear picture end to end . – Beer Gupta Sep 13 '16 at 21:20
0

If your service and controller are stateless, it's ok to inject one to another.

You should not declare any variable which keeps a state in these classes. final variables are ok.

If all operations are defined in methods and they don't use any variables of the classes, dependency injection that you're doing is totally safe.

mokarakaya
  • 723
  • 1
  • 11
  • 22
  • exactly my point ,could you please explain if the same happen when I autowired datasoruce using mybatis and jdbc in the service class – Beer Gupta Sep 13 '16 at 21:18
  • for instance;https://github.com/mkarakaya/spring-boot-multi-module-maven/blob/master/api/src/main/java/com/apiDemo/service/BanksService.java As you see, every object is created and used in methods so it's totally stateless. and repository class is singleton. – mokarakaya Sep 13 '16 at 21:25
  • Thanks for answer :) – Beer Gupta Sep 13 '16 at 21:35
  • i also found this ans very helpful too http://tutorials.jenkov.com/java-concurrency/java-memory-model.html – Beer Gupta Sep 13 '16 at 22:08
0

That's why you need to use @Autowired when you declare a dependent service. Effectively handing the initialization process to the Spring framework instead of instantiating it yourself. Since Spring only has stateless beans, you're injecting one stateless singleton to another stateless singleton, so there's no need to manage thread manually.

Christopher Yang
  • 3,769
  • 4
  • 30
  • 27