Is it possible to set a session attribute in a manager class (class which is not a controller and is marked as #component)?
The scenario is like this, from my Controller i'm calling a manager class which does some logic. I want to store the result of this logic in the session, so that i can use it in the later requests.
No. #SessionAttribute is a controller-specific concept. To get similar behaviour in other components you can use session-scoped beans.
Related
In a spring MVC app , by default all beans are singleton ,but what should be the standard scopes for below classes according to good programming practices:
1.DAO classes
2.Controller classes
3.DTO classes
4.Service classes
I have read that DAO and Controller classes should be singleton scoped and DTO classes should not be beans so not annotated, whenever required, DTO classes should be instantiated using "new".
What will be the scope of #Service classes ?
And Which classes will have the Request and Session scopes if none of the above classes are created in these 2 scopes?
First of all not classes, but Spring managed beans have a scope. Difference is that you can have classes in your application that you didn't configure to be managed by Spring (So for example you didn't provide #Component annotation)
For the Spring managed beans default scope is Singleton. That means Spring container will provide the same instance everytime you ask for that bean to be autowired.
You can change that default scope with for example #Scopeannotation. So to answer your question, all of the above mentioned choices would have default scope of singleton but you could changed that to be requestor sessionscope if you would like (only applicable in web applications though). You can read more about setting scopes here.
ps. DTO classes are usually not declared to be managed by Spring - letting Spring manage a simple data transfer object doesn't make much sense.
So basically two things to consider here. The 1st is that if a bean is required to be declared as a spring bean . It depends on if you need to use the spring features for this class such as #Transactional , #Async , #PreAuthorize , #Autowired (i.e dependency injection) , or ensure the bean has certain scope etc. If not , it is simpler not define it as a spring bean and simply create it by yourself.
So the following types of the classes are required to define them as spring bean in most cases:
DAO because most probably need to inject EntityManager or JdbcTemplate to it
Controller because it is a part of spring-mvc and you need to define it as a bean such that you can use #RequestMapping / #GetMapping / #PostMapping / #PutMapping / #DeletMapping / #PatchMapping etc. on its method.
Service class because you need to inject it into the controller and you need to use #Transactional to manage the DB transaction for its method.
For DTO , in most case you can create it by yourself since it is just a data container in nature and does not require to use any spring features.
The 2nd thing to consider is what scope does a bean should be. You mainly need to think about if an instance of that class is okay to be executed safely by multiple request (i.e thread) concurrently. If yes , you can simply use the default singleton scope. If not , you can think about if you want each HTTP request (i.e #RequestScope) or each HTTP session (i.e. #SessionScope) has their own instance of that class to work with. For example , if you are implementing some shopping cart , you most probably want that the HTTP session has their won instance of a shopping cart and so you should use #SessionScope for the shopping cart.
I am little new in Spring.
Having one question that did i need to annotate every class.
example: I have one controller and one is logic class. Controller autowired that class, So i need to annotate that class or not?
No you don't have to annotate all your classes with #Component you can but you don't have to. What you need to do is make your bean instance manage by Spring. You can do that in various ways.
(obviously) annotate the bean with #Component (or one of the specialized versions like #Service, #Controller etc.)
Write XML configuration and manually define your beans
Write Java configuration and use #Bean method to define your beans.
Either way will work.
I am new to Spring/JSF.
I have a controller which is annotated by #Component which have a #Autowired class UserClass which has,
#Scope(value=org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE)
I need to create a new UserClass instance for each new request so my controller is annotated with #Scope("request") which works perfectly(Creating new instance for each request) with this annotation.
But it broke the ajax calls in <p:dataTable> selection, commondLink, <f:setPropertyActionListener...
NOTE : if I change the #Scope("request") to #ViewScoped the ajax works but my UserClass becomes singleton and all the data is shared between the threads.
I googled and got to know we need to either use JSF annotations or Spring but here I am using only Spring annotations.
And I found this, PrimeFaces doesn't work when bean scope is request but couldn't understand.
A component library like Primefaces heavily relies in a stateful model, which means using at least the view scope in your managed beans. If you use the request scope you'll be recreating the managed bean for every single request, including ajax requests, which I guess it isn't what you want (not the way to go with JSF, at least).
Your best is to use a custom Spring Scope in order to emulate the JSF view scope. I like this approach from the PF team (a bit old post, but still you can tune it for newer Spring versions) or this one, which is more elaborated.
Given a spring bean that is configured with session scope such as:
#Component
#Scope(proxyMode=ScopedProxyMode.TARGET_CLASS,value=WebApplicationContext.SCOPE_SESSION)
public class SomeBean {
}
Is there some way to control the name that Spring will store the bean under in the http session?
By default spring seams to use the session key scopedTarget.someBean is there anything I can add to the annotations to explicitly specify the attribute name in the Session?
I'd use:
#Component (value="mySpecialName")
#Scope (value="session")
You cannot. The scopedTarget part is hardcoded in the scoped proxy creation in Spring. So without rewriting parts of the framework that simply isn't possible.
The name is hardcoded in the ScopedProxyBeanDefinitionDecorator which delegates to the ScopedProxyUtils.
The fact that you use a scoped proxy is something internal for the framework. You probably want to use it to store something in the session and retrieve it in a page or something like that. Don't, just expose the regular bean which will delegate to the proper scoped instance.
I want to clear some moments about integrating spring and struts. I have only one action class per application extended from MappingDispatchAction. So, actually my app when doing something uses not Action objects, but methods from my action. All I want from spring is to initialize this action and all for now. Just simply set DAO object. I looked through documentation, but I don't understand following:
We use action path from struts-config.xml as a name of bean in action-servlet.xml. Okay, but am I supposed to write beans in action-servlet.xml for every path name and set this poor DAO ref or what ?
The Struts 1 config file will use the DelegatingActionProxy class as the type attribute for all action configurations.
The Spring config file will contain the bean definitions of each action implementation. I don't know what DAO you're talking about, but actions that require DAO or service injection need to have them listed, yes--that's what Spring configuration is.
You may also be able to use annotations if you're not interested in using XML configuration, or use bean inheritance if many beans share the same DAO/service/etc. property values.