What is the difference between autowiring and object creation? - java

What is the difference, if I autowire a class and provide value and instantiate an object of class and provide some value?
For example-
#Autowired
private UserService userService;
userService.findUser(userName, password);
And
User user = new user();
userService.findUser(user.getuserName(),user.getpassword());
What is the difference in Autowiring and sending the data and instantiating the object and sending the data to some service class?
I'm trying to clarify the concepts in spring.

When you use #Autowired you are leaving it up to the Spring framework to find and instantiate the userService. This is usually controlled through some configuration file or some other configuration, which allows you to change the behaviour of your application without changing the code itself.
On the other hand, when you instantiate the object yourself, you are specifying which object you are after and what type of class you want. This could leave you with less ambiguous code since you know what type of object is being initialized, but to make a change in your application's behaviour you would need to change your code.
In essence, the first option is less coupled than the second option, which is usually the recommended way of building things.

Your example doesn't make a lot of sense; this User class, which looks like some plain data object, isn't adding anything to the second snippet.
The idea of "autowiring" is that some class, like maybe a Web controller, will need a UserService in order to get its work done. When Spring autowires the UserService, it goes into the context and finds a matching object and provides it to the class that needs it. This is technically separate from creating the object.
That said, the best practice is to use constructor injection--simply declare the other objects you need as constructor parameters and annotate the constructor with #Autowired (or #Inject). Spring will know to look up all the dependencies you need and call the constructor with them. This means that it's also very simple to provide mocks of those objects for testing or development.

Well, the main difference is that in case u use #Autowired the object is also created, however, it's created by container and container decide when to do that.
I want to give you a simple example:
You have four classes 1,2,3 and 4. Three of them (1,2,3) uses the 4th. So, if you use new(), it`s hard to decide where to create object(in class 1, or 2, or 3, or even in each of them) of 4th class. Moreover, later you can delete class with object initialization and other 2 classes won't work (in case you created one object). Autowired annotation injects the object but you don't initialize object in class, so no problems appear
This is like the simplest answer.

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.

Related

Is there any way to pass #Autowired variable to some other class in a Spring Boot application?

In my Spring Boot application, I have class A. In that class, I have declared my DAO layer variable with #Autowired annotation. I have a separate Java library which contains class B (which has a method that accepts generic parameters). I want to send the #Autowired variable from class A as a parameter to the method of class B and perform some operation with that variable in class B's method.
Is there any way to achieve this? Will the second class be aware of the context?
Will the second class be aware of the context?
I assume, by second class you meant class B. ClassB doesnt need to be aware of the context. All it care is, it needs a non-null Object of DAO layer as method argument.
So, the question is, at what point are you trying to invoke the method in class B. If you are invoking it before spring completes it's part, then all you will get is null. Try calling the ClassB.method() from #PostConstruct annotated method and see whether you are still getting null reference for DAO member variable. If that's the case look at your spring bean instantiation.
Yes you can do it, but it is not a good practice. If you want to create a separate library then make it simple. You are increasing the dependency.
It is always recommended to follow loos coupling principle while building application.

Is it possible to implement/override an abstract method with reflection?

I have a question about Reflection, but the motivation is from using Spring Framework.
Consider this project, which is a sort of Minimum Working Example version of a deployed project.
In the ProjectionResourceProcessorConfig class, I have an entityProjectionResourceProcessor method for every projection, and every entity in the database have a few projections. That's about 60 methods.
I don't want to keep this up because of the obvious maintenance disadvantage. I want to use Reflection in order to automatically register one bean for every projection class.
The postProcessBeanDefinitionRegistry method in the ProjectionResourceProcessorConfig class shows that I can get the list of classes I want to use to register one bean for each and shows how to register a bean programatically.
However, because I need to use the ProjectionResourceProcessor class, I need to override the getEntityClass method. I haven't been able to find a way to do that programatically. That's why I've declared the inner class. It shows the programatic bean registration working, but it falls in the same issue as requiring a piece of code for every bean.
Apart from reflection, I tried to use the setMethodOverrides method of the RootBeanDefinition class to override that method, but I couldn't manage to understand how to use that method. Google couldn't find any documentation or usage example (except for a vaguely related Chinese post with copies on several different websites).
I also tried to use the MethodReplacer class but I haven't found how to use it with annotation driven configuration.
I also tried to replace the getEntityClass method by a variable and replace the variable's value by reflection, but apparently when the variable is read the value that was set in the super class is the one that is retrieved.
To test the project, run the tests at DemoApplicationTests. It will print the projection of some entities. If they have links, it's working.
Is it possible to do what I want? If it is, how?
Thanks in advance.

Spring: newing up and autowiring: Can a newed up object never use Autowired?

I understand that if you directly new up an object that Spring has now way to inject a dependency specified by #Autowired.
However, say you have a UI in which create new Customer objects. I believe that newing up a Customer prior to persisting it is the only way to go. If that is so, what if I want Customer to have some complex behavior that requires access to some service that would normally be autowired?
Is it possible that once the Customer object is saved and then retrieved at that point Spring will be able to inject the autowired dependencies? So that the mistake is trying to use the Customer object "too early?"
My main question is, Is wanting to use Autowired in a newed up object reflective of a design flaw?
EDIT: I have seen ways that a newed up object can in fact use Autowire but again my question is, for common classes like Customer, User, Person, etc. is it unusual for them to even need to use #Autowired? Should they essentially be data-only objects? I seem to have need to both create new objects and have those objects exhibit behavior but maybe I am doing something wrong design-wise.
You may create multiple instances of an object on the fly with an org.springframework.beans.factory.ObjectFactory<T> in Spring, which is like the javax.enterprise.inject.Instance<T> interface of Java EE CDI. See: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/ObjectFactory.html
#Autowired
ObjectFactory<Customer> customerFactory;
...
Customer newCustomer = customerFactory.get();
...
If the "Customer" is your entity class, you should avoid autowiring services.
How does your implementation look like? Could you provide more details?
I believe that Sergii's confirmation that the design is flawed is correct and I communicated with the app's original designer. So even if one could jump through hoops to autowire newed-up objects, it is not consistent with the original design or apparently Spring Boot's approach according to Sergii.
I see a way of doing what I need without autowiring -- the newed-up objects' complex behavior is now done elsewhere in the application.

What beans do you wire in a spring mvc app?

I am wiring my UserService type classes using spring's IOC.
But what about my User class?
I have a interface User, then a UserImpl class.
In my controller action's do I just do:
User u = new UserImpl();
Or would it sometimes make sense to use IOC for this also?
Sometimes I use a different constructor also when instantiating a class, based on some conditions. I guess your stuck in these situations?
It will not make sense to use dependency injection or IOC for your business objects like User because business objects are not the dependencies of the class they are the part of the class using them.
Spring IOC, by default, will create Singletons for you. Which means all user threads using your app will share that single instance of class. This is generally fine for Service type classes. If needed this singleton behavior can be changed to object per request (prototype), but this will cause you to change this setting for the users of the non-sigleton object as well.
Domain/business classes are state-full, it's easiest to create such objects once-per-request in order to avoid concurrency issues.

Is there ever a case for 'new' when using dependency injection?

Does dependency injection mean that you don't ever need the 'new' keyword? Or is it reasonable to directly create simple leaf classes such as collections?
In the example below I inject the comparator, query and dao, but the SortedSet is directly instantiated:
public Iterable<Employee> getRecentHires()
{
SortedSet<Employee> entries = new TreeSet<Employee>(comparator);
entries.addAll(employeeDao.findAll(query));
return entries;
}
Just because Dependency Injection is a useful pattern doesn't mean that we use it for everything. Even when using DI, there will often be a need for new. Don't delete new just yet.
One way I typically decide whether or not to use dependency injection is whether or not I need to mock or stub out the collaborating class when writing a unit test for the class under test. For instance, in your example you (correctly) are injecting the DAO because if you write a unit test for your class, you probably don't want any data to actually be written to the database. Or perhaps a collaborating class writes files to the filesystem or is dependent on an external resource. Or the behavior is unpredictable or difficult to account for in a unit test. In those cases it's best to inject those dependencies.
For collaborating classes like TreeSet, I normally would not inject those because there is usually no need to mock out simple classes like these.
One final note: when a field cannot be injected for whatever reason, but I still would like to mock it out in a test, I have found the Junit-addons PrivateAccessor class helpful to be able to switch the class's private field to a mock object created by EasyMock (or jMock or whatever other mocking framework you prefer).
There is nothing wrong with using new like how it's shown in your code snippet.
Consider the case of wanting to append String snippets. Why would you want to ask the injector for a StringBuilder ?
In another situation that I've faced, I needed to have a thread running in accordance to the lifecycle of my container. In that case, I had to do a new Thread() because my Injector was created after the callback method for container startup was called. And once the injector was ready, I hand injected some managed classes into my Thread subclass.
Yes, of course.
Dependency injection is meant for situations where there could be several possible instantiation targets of which the client may not be aware (or capable of making a choice) of compile time.
However, there are enough situations where you do know exactly what you want to instantiate, so there is no need for DI.
This is just like invoking functions in object-oriented langauges: just because you can use dynamic binding, doesn't mean that you can't use good old static dispatching (e.g., when you split your method into several private operations).
My thinking is that DI is awesome and great to wire layers and also pieces of your code that needs sto be flexible to potential change. Sure we can say everything can potentially need changing, but we all know in practice some stuff just wont be touched.
So when DI is overkill I use 'new' and just let it roll.
Ex: for me wiring a Model to the View to the Controller layer.. it's always done via DI. Any Algorithms my apps uses, DI and also any pluggable reflective code, DI. Database layer.. DI but pretty much any other object being used in my system is handled with a common 'new'.
hope this helps.
It is true that in today, framework-driven environment you instantiate objects less and less. For example, Servlets are instantiated by servlet container, beans in Spring instantiated with Spring etc.
Still, when using persistence layer, you will instantiate your persisted objects before they have been persisted. When using Hibernate, for example you will call new on your persisted object before calling save on your HibernateTemplate.

Categories

Resources