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.
Related
I'm just starting to pick up Spring, coming from a purely Java EE background, so stuff like IOC and dependency injection is all kinda new to me. As per the Spring docs, I understand that for any class to call on instances of its dependencies, I can choose to autowire those dependencies as a form of dependency injection. And that this is actually aside from the usual instance declaration we always do in java like below: Animal animal1 = new Animal()
In my one of my little test Spring boot project services, I noticed that I end up doing both dependency injection and normal class instantiation. I use JPA Repository to craft my repo layer, and autowire the repo classes so I can use them like eg.
#Autowired
customerAccountRepo
This is all fine. I also have a DAO customerMembershipValidity whose attributes are other declared POJOs and has some public helper functions within to set the DAO's attributes. In order to use this DAO, however, I find myself creating multiple instances of the DAO the traditional way, instantiating
CustomerMembershipValidity customerMembershipValidity1 = new CustomerMembershipValidity() multiple times throughout the service to call on public helper methods like customerMembershipValidity.setNewExpiry(). I didnt think there would be a need to autowire this since I'm dealing with a DAO or POJO, not another service... or should I?
For now, the code seems functional when I do my unit-testing, but I would like to know if this would harm the overall longevity and sensibility of the code, or if it's forseeable to end up breaking in E2E when I run the Spring Boot application.
I have a few recommendations:
DAO should be a singleton Spring Bean that you inject into service bean(s) that need it. Make sure there is no mutable shared state in your DAO - just database operations.
The DAOs I write might use mapper functions to map ResultSet to objects/collections, but I don't see the need for helpers.
Spring preference is to use constructor injection. You should not use setter or autowired attribute to inject dependencies.
If you use new, that means the object is not under Spring's control. It's appropriate to call new for objects in method scope, but not a Spring Bean like a DAO.
Unit testing and production are two different things. I prefer to leave Spring out of unit testing. I call new for JUnit tests, but not production code. Once I've tested the DAO, I can use mocks for services that depend on it.
You're smart to take up Spring and leave Java EE behind. It's a twenty year old dead standard.
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.
I'm a new Guice user, having been a long-time user of Spring IoC. I have a number of #Singleton classes for my service tier, which I understand is roughly equivalent to Spring's default bean scope.
However, when I am using #Inject in my Wicket pages a CGLib proxy of the target objects is created each time the page is constructed, thus creating new instances of my supposed-singletons.
Note that I'm injecting concrete classes, not interfaces.
How can I use #Inject and retrieve the single singleton instance of my Guice-injected objects?
Updated: Solution as per Sven's accepted answer
Inject interfaces in Wicket components rather than concrete classes. Despite much discussion on the subject in the linked thread, this appear to be the only practical solution.
The following issue gives some background:
https://issues.apache.org/jira/browse/WICKET-1130
How would you extract something prior 2.5 version from .xml config? It bothers me because if #Autowired is removed from my arsenal I would not really know what to do.
Say I want to use some DAO implementation.
In service class I usually write:
#Autowired
someDaoInterface generalDao;
Then I typically call
generalDao.someInterfaceMethod(someParam param);
How would I extract implementation from config in Spring 2.0 to use this method?
Is it as dumb as just: new ApplicationContext(pathToXml) and then use .getBean or there is other way?
Why do I ask for taking bean out from configuration file?
Because in Spring MVC how can you perform your logic without getting beans out from the application context.
If you have #Controller handler then you need to make calls to the service classes' methods? So they should be somehow retrieved from the context and the only way so far is using #Autowired? Then I would also want to populate Service classes as I stated in previous example with DAO classes and they also need to be retrieved from the application context, so I would be able to write logic for service classes themself. How would people do it in the past?
I see the #Autowired as the only mean of taking something out, not because it is convenient to wire automatically - I am perfectly ok with XML.
You still have option to wire it explicitely via property or constructor parameter. (Anyway, autowired is not going to work if there is ambiguity in your container )
Of course, you can use application context and getBean() in your java code, but it violates DI pattern and makes all the spring stuff useless. Purpose of DI is to decouple your business loginc from implementation details - it's not business logic it's how and where it dependencies come from. Dependencies are just there.
By using ApplicationContext.getBean() you are breaking this pattern, and introduce dependency to:
spring itself
your configuration names
After you done this, you can as well drop use of DI and spring because you just voided all the advandages DI is providing to you. (BTW, #Autowired also introduces dependency to spring, and violates DI pattern, it also implies that there is only one instance available)
Also, answer is: in ideal case there shall be no reference to spring in your code at all.
No imports, no annotations - just interfaces of collaborating entities.
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.