Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring: new() operator and autowired together

If I use Spring, which of these two methods is more correct. Can I use the new() operator even if I use dipendency injection?.Can I mix both? I would like to have some clarification on these concepts. Thanks

First method:

@RequestMapping(method=RequestMethod.GET)
public String create(Model model){
 model.addAttribute(new User());
 return "index";
}

Second Method:

@Autowired
User user;

@RequestMapping(method=RequestMethod.GET)
public String create(Model model){
 model.addAttribute(user);
 return "index";
}
like image 997
Alex Avatar asked Sep 30 '22 09:09

Alex


People also ask

Does Autowired create a new instance?

When you autowire a prototype bean, Spring will initialize a new instance of the bean. If you autowire the bean in multiple places, then Spring will create a new instance for every place you autowire the bean.

Can we use qualifier with Autowired?

You can use @Qualifier along with @Autowired to help Spring Framework find the right bean to autowire. Spring Framework will ask you explicitly select the bean if ambiguous bean types are found, in which case you should provide the qualifier.

Does @component need @autowired?

There are different ways to create Spring beans. One is by using @Component with classpath scanning, other ways are by using XML config or Java config, by having @Bean methods in a @Configuration class. So the answer is: No, @Autowired does not necessarily mean you must also use @Component .

What is difference between Autowired and new object creation?

the above answers are good i would like to tell a major difference between them . the purpose of autowiring is to avoid the dependencies between the class if you are creating objects with new making a change to one class will effect all the classes.


1 Answers

By using dependency injection does not mean that the use of new operator is automatically prohibited throughout your code. It's just different approaches applied to different requirements.

A web application in spring is composed of a number of collaborating beans that are instantiated by the framework and (unless overriding the default scope) are singletons. This means that they must not preserve any state since they are shared across all requests (threads). In other words if you autowire the User object (or any other model attribute), it is created on application context initialization and the same instance is given to any user request. This also means that if a request modifies the object, other requests will see the modification as well. Needless to say this is erroneous behavior in multithreaded applications because your User object (or other model attribute) belongs to the request, so it must have the very narrow scope of a method invocation, or session at most.

You can also have spring create beans with different scopes for you, but for a simple scenario of a model attribute initialization, the new operator is sufficient. See the following documentation if interested in bean scopes : Bean scopes

So in your use case, the second method is totally wrong. But you can also delegate the creation of your model attributes to spring if they are used as command objects (i.e. if you want to bind request parameters to them). Just add it in the method signature (with or without the modelattribute annotation).

So you may also write the above code as

@RequestMapping(method=RequestMethod.GET)
public String create(@ModelAttribute User user){     
 return "index";
}

see also : Supported method argument types

like image 121
gregdim Avatar answered Oct 04 '22 02:10

gregdim