I am using spring framework for dependency injection, but I simply cannot find out, if I am using it right. Imagine this case - it is not real, but just to explain my problem. I have a spring boot application which connects with websocket to some endpoints. I have a class which has all available methods for this client, stores all needed data for client etc., let's say Client. Then I have a static list which holds all connected clients List<Client>. I need that the Client class is Spring managed bean, as I need to use #Service and all other spring features (#Value, #Async) etc.
The problem is, spring beans are singletons right? How can I instantiate then object from a class which should be spring managed but on the other hand there should be multiple instances of this class?? I cannot use new right?`
It isn't necessarily true that spring-created objects are singletons; this is merely the default. Spring supports a variety of different options for determining when a new object is created versus an old one being recycled. You should look at the documentation for the "scope" attribute and determine what is most appropriate for your application.
Alternatively, you can create the object yourself using new and then request Spring to configure it for you using the technique described at http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-atconfigurable
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.
My questions are about the lifecycle of controllers in the Play framework for Java, if the controllers are stateful instances or stateless with static methods, and how to use dependency injection in the controller code.
Is each web request handled by a new instance of a Play controller class, i.e. can a controller store state in fields such as services injected into the controller constructor?
(where in the documentation is it explained?)
Has the Play framework changed since earlier versions (and if so, at what version?) regarding if controllers are stateful instances or stateless controllers with static methods?
Where can you see code examples about how the framework injects services into a controller instance when stateful controller is used and example of how to inject services into a static controller method?
Regarding the latter, i.e. injection into a static method I suppose that would either have to be a parameter to the method which the frameworks will add, or if not possible you maybe instead will have to use a service locator from within the method e.g. instantiate a Guice module class and then use "injector.getInstance" from within the static controller method.
This subject is touched in the section "Dependency injecting controllers" at the following page:
https://www.playframework.com/documentation/2.4.x/JavaDependencyInjection
However, it does not show with code how to actually inject services into a controller instance (but probably the same way as other "components" i.e. with #Inject annotation) and certainly it does not currently show how to use DI with a static controller method.
I am confused about these things because I have not found documentation being clear about my questions, and I have also read in a Play book (from 2013) that the controller methods should be programmed as stateless and the controller methods should be static.
However, when now using activator for generating a Play application for Java with the latest Play version (2.4.6) I can see that the generated Controller method (Application.index) is NOT static.
Also, at the following documentation page, the controller method is NOT static:
https://www.playframework.com/documentation/2.4.x/JavaActions
This is confusing, and since it is VERY fundamental to understand whether or not each request is handled by a Controller instance or not (i.e. if state can be used) I think this should be better documented at the page about Controller/Actions than the current documentation (the above linked page) which is not explaining it.
The documentation about dependency injection touches the subject about static and non-static methods at the section "Dependency injecting controllers" mentioning "static routes generator" but I think it should be better explained including code examples.
If someone in the Play team is reading this question, then please add some information to the above linked pages, for example please do mention (if my understanding is correct) that in previous versions of Play the controller methods were static and for those versions you should never store state in fields, but in later versions (beginning from version x?) each request is handled by an instance of a controller and can therefore use state (e.g. constructor parameters injected by the framework).
Please also provide code examples about injection used with static controller methods and injection into stateful controller instances with one instance per request.
The section "Component lifecycle" in the dependency injection page only mentions "components" but I think it should also be explicit about the controller lifecycle and its injection, since it is such a fundamental and important knowledge to communicate clearly to all developers to avoid bugs caused by misunderstandings about being stateful or not.
Is each web request handled by a new instance of a Play controller class, i.e. can a controller store state in fields such as services injected into the controller constructor? (where in the documentation is it explained?)
As far as I can tell, controllers are by default singleton objects. This is not clearly documented, but it is implied that controller instances are reused. See the migration guide for Playframework 2.4:
The injected routes generator also supports the # operator on routes, but it has a slightly different meaning (since everything is injected), if you prefix a controller with #, instead of that controller being directly injected, a JSR 330 Provider for that controller will be injected. This can be used, for example, to eliminate circular dependency issues, or if you want a new action instantiated per request.
Also, check this commend made by James Roper (Play core committer) about if controllers are singleton or not:
Not really - if using Guice, each time the controller is injected into something, a new instance will be created by default. That said, the router is a singleton, and so by association, the controllers it invokes are singleton. But if you inject a controller somewhere else, it will be instantiated newly for that component.
This suggests that the default is to reuse controller instances when responding to requests and, if you want a new action per request, you need to use the syntax described in the migration guide. But... since I'm more inclined to prove and try things instead of just believe, I've created a simple controller to check that statement:
package controllers
import play.api._
import play.api.mvc._
class Application extends Controller {
def index = Action {
println(this)
Ok(views.html.index("Your new application is ready."))
}
}
Doing multiple requests to this action prints the same object identity for all the requests made. But, if I use the # operator on my routes, I start to get different identities for each request. So, yes, controllers are (kind of) singletons by default.
Has the Play framework changed since earlier versions (and if so, at what version?) regarding if controllers are stateful instances or stateless controllers with static methods?
By default, Play had always advocated stateless controllers, as you can see at the project homepage:
Play is based on a lightweight, stateless, web-friendly architecture.
That had not changed. So, you should not use controllers' fields/properties to keep data that changes over time/requests. Instead, just use controllers' fields/properties to keep a reference to other components/services that are also stateless.
Where can you see code examples about how the framework injects services into a controller instance when stateful controller is used and example of how to inject services into a static controller method?
Regarding code examples, Lightbend templates repository is the place to go. Here are some examples that use dependency injection at the controllers level:
https://github.com/adrianhurt/play-api-rest-seed
https://github.com/knoldus/playing-reactive-mongo
https://github.com/KyleU/boilerplay
Dependency Injection with static methods is not supported, and that is why Playframework stills offers old apis to use with static methods. The rule of thumb here is: choose between DI and static methods. Trying to use both will just bring complexity to your application.
Ok, thank you marcospereira.
I have now also confirmed that you indeed get different instances (different toString values which can be printed/logged in a controller method) of the controller for each request.
For those who are interested, the solution (to get different instances of controller class for each request) is to use for example the following:
GET / #controllers.Application.index()
instead of the following:
GET / controllers.Application.index()
in the file "conf/routes"
AND to also use the following:
routesGenerator := InjectedRoutesGenerator
instead of the following:
routesGenerator := StaticRoutesGenerator
in the file "build.sbt"
Regarding the statement that Play has a "stateless" architecture:
Maybe I am wrong, but as far as I understand the terminology, the "stateless" means that the web server does not store any state between requests?
The word "stateless" does not mean that a controller instance can not use fields, e.g. injected into the constructor.
If an injected object is stored as a field in a controller, then that field is a "state" of the controller.
Therefore, even if you use "InjectedRoutesGenerator" and the "#" prefix to get "stateful" controller instances, that injected "state" is only stored within one request, so you can still say that the framework itself is "stateless" since the server does not store any state between multiple requests.
Please do correct me if I have misunderstood something about Play being stateless.
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.
I have clear understanding of the various scopes of Spring beans. But I am looking for some use cases of prototype scope of a bean in enterprise tier projects. It would be great if you can share some real life use cases of the prototype scope (not the request scope).
As someone who previously worked at SpringSource and have talked to the developers on this topic. Here is my take. Prototype is great for testing things out, hence the name prototype and not create new or something more description of creating a new instance of the bean each and every time you request it from the Spring container.
I have also found in my use over the years that I cannot think of any other place where prototype makes sense in any real-world production application. If your object holds state, it typically shouldn't be a Spring bean. I have found in all the applications I have worked on that all beans are Services, Repositories, and Singleton non state holding objects where I need to add features like Transactionality, JPA, JMS and the likes that give us the enterprise features that POJOs don't have.
The objects in my system that hold state are my Entities and View DTOs maybe, or other things that just make no sense to be a Spring Bean. So therefore in my applications in production there hasn't been a single "prototype" bean.
I used prototype beans to declare configured form elements (a textbox configured to validate names, e-mail addresses for example) and get "living" instances of them for every form being created in my webapp. The details are not important, only the principle, that I would summarize this way:
There is a class that has many config parameters
You need to create instances of it with a set of predefined configuration (fancy1, fancy2, stc.)
Think of the applicationContext.getBean("myBeanConfiguredFancy1") as a kind of factory method that creates the instance as preconfigured in the xml
I have used prototype mostly in conjunction with spring lookup-method. My application is a game server that needs to decode incoming bytes at tcp port. Consider the following bean definition
<bean id="channelBufferProtocol" class="org.menacheri.protocols.impl.ChannelBufferProtocol">
<lookup-method name="createLengthBasedFrameDecoder" bean="lengthFieldBasedFrameDecoder"/>
<property name="eventDecoder" ref="eventDecoder"></property>
<property name="lengthFieldPrepender" ref="lengthFieldPrepender"></property>
<property name="eventEncoder" ref="eventEncoder"></property>
</bean>
Inside the protocol implementation class, I have the following code to create the frame decoder pipeline.addLast("lengthDecoder", createLengthBasedFrameDecoder()); When this method is invoked, spring will create a new frame decoder instance and return it.
The bean returned by bean="lengthFieldBasedFrameDecoder" needs to be of scope prototype, since it is a stateful bean in my app.
Note: A protocol is nothing but a specific set of decoders and encoders chained together. "Chain of responsibility" design pattern.
We can use prototype scope in case of model classes(also called as Entities in hibernate) as application need different instances of model class for each thread/request.
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.