Finalize beans of a certain user - java

I need a specific scope in my spring-managed (w/ spring-security) web application. But this scope must have a narrower scope than session and wider than request. Corresponding beans should be initialized and destructed on certain cases, within current session. But for sure only destructed for the user who requested such.
I successfully implement a custom-scope but it is not user-aware and when I try to finalize it, all created beans on that scope are finalized.
Is there any way to initialize beans with e.g logged user name?
In a nutshell, I need to initialize some of the variables on such beans on certain cases, that's why I want to destroy and re-initialize them.
Any suggestion will be well accepted,
Thanks all.
Edit: As #Stefan suggested to use webflow, even that'll probably solve our issues i think it doesn't seem an acceptable method because our bunch of pages are dependent to fields defined in spring beans. Now we have to bind them to viewscope/flowscope.
I still need a quicker way to handle this issue,
Thanks.

You might have a look at Spring Webflow. It works with JSF and has a 'flow scope' that is between request and session scope.

Related

Spring: Scoped fields

I wrote this idea on the Spring JIRA and even though I know this is not a key feature and has minor priority, I'd still expect some answer by now. I publicize the idea, because I want to know what you guys think about it, if it's cool and I should implement it myself, or is the need for this is a sign of bad architecture.
So the idea itself is - as the title suggests - is a field in a Spring Bean, which has a different scope then the bean itself. We already have something like this, in the shape of scoped proxies, however it works only for bean dependencies. I might want to store a list of Strings of session scope in a bean of singleton scope. I, then have to create a new bean, with scope of session for one field and some functions to use that field. It seems a waste of code and I'd find it bad, because I wouldn't be able to use that bean anywhere else, because it'd already have that data the first class put into it.
I could rephrase the mess above and say that I want to have named beans with arbitrary type (so not necessarily spring beans) and on top of the scope we configure it to have, that field would also be different for every instance of the parent class.
This could make a field instance broader than a prototype scoped bean, but also less broad then the actual scope we'd like to use it in. Kind of a middle ground.
Here is the JIRA issue I wrote: https://jira.spring.io/browse/SPR-16971
In my understanding, Scopes only work with Dependency Injection as it's the DI Container that decides if it should return a new instance or an already existing one. So everything that is #Autowired can be scoped.
I can't imagine how scoping a normal field would work. If I change it, should it change in all other objects that "use" it? I would have to be some kind of proxy object then and neve a primivive value. If on the other hand you have a proxy object, why not use the currently available autowire mechanism.

View scope bean injecting application scope and modify app scope data. Bad practice?

I have a view scoped bean and based on the user input, it might need to change the values of the application scope bean for the entire app to use the new values. It seems to be a bad practice to change values of application scope bean in real time. The application bean loads all the values of support tables, with the admin part of my app, I want the admin users to be able to add things to the support tables and then everyone should be able to use the new values.
The problem I'm seeing is that the view bean gets a new instance of the injected managed property each time the page has to go back to the managed bean, I also see a similar problem when injecting session scope into view scope and changing values.
Thanks.
There are two separate problems here.
Whether it is good practice to modify global application state via in-memory beans depends on the specifics of what you are doing, how much state there is, how its going to be persisted, whether the application is in a clustered environment, etc.
Stack Overflow is unsuited to doing a detailed architectural review.
The problem I'm seeing is that the view bean gets a new instance of the injected managed property each time the page has to go back to the managed bean, I also see a similar problem when injecting session scope into view scope and changing values.
This does not sound right at all. You might see new instances (proxied beans) if you're using CDI but you mention managed properties so I guess not. Application scoped beans are placed into the application map and remain there until the application is stopped.
So, there is something wrong with your application logic or you have omitted some relevant detail about your software stack or environment.

Java EE 6 - #PreDestroy in ViewScoped & Session beans never called

As I wrote in this topic I need to invoke some action when user close or change page. I thought I could use #PreDestroy in my view scoped bean, but it is never called (even when session expires). Is this a bug? I use Glassfish 3.1.2.
Any other suggestions how can I call bean method when user leave page? Is javascript window.onunload good idea?
Even if the bean is view scoped, it's the container's responsibility to decide when to collect and destroy unused resources.
The annotations used for defining a scope indicate how long a managed bean has to survive, but you are not guaranteed about when they'll be destroyed.
As you have suggested, JavaScript can be a solution for your problem. See also this answer: How to detect unsaved data in form when user leaves the page?

.java terms and random words clarification

Im really new to java, jsf, jsp, and I need to learn how it works quickly. So the website Im using to practise has some terms etc that I dont know what they mean and Im hoping somebody can explain what they mean and how/what they are used for:)
Requestscoped
Applicationscoped
Sessionscoped
EntityManager
and could someone walk me through what these lines do?
#RequestScoped
public class Dao {
#DataRepository
#Inject
private EntityManager entityManager;
First of all, in Java (5 and higher), "things" starting with a # (e.g. #Deprecated) are called annotations.
Annotations provide data about a
program that is not part of the
program itself. They have no direct
effect on the operation of the code
they annotate.
Your JavaBeans needs to be configured to a scope if you want to use it in JSF (Definitions can be found here).
#RequestScoped: Objects with this scope are visible from the start of the request until the end
of the request. Request scope starts at the beginning of a request and ends when the
response has been sent to the client. If the request is forwarded, the objects are visible
in the forwarded page, because that page is still part of the same request/response
cycle. Objects with request scope can use other objects with none, request, session,
or application scope. If you have to think it in terms of servlet, the managed bean is stored in the HttpServletRequest until the end of the request (when the response is sent to the client). After that, the bean no longer exists in the request.
#SessionScoped: An object with session scope is visible for any request/response cycle that
belongs to a session. Objects with this scope have their state persisted between
requests and last until the object or the session is invalidated. Objects with session
scope can use other objects with none, session, or application scope. Basically, these objects are stored in a HttpSession (refer to Servlets again). Each session has a session ID (known as JSESSIONID) that the bean is associated with.
ApplicationScoped: An object with application scope is visible in all request/response cycles
for all clients using the application, for as long as the application is active. In terms of Servlet, this could be, managed bean stored in a ServletConfig.
#NoneScoped: Objects with this scope are not visible in any JSF page. When used in the configuration file, they indicate managed beans that are used by other managed beans in the application. Objects with none scope can use other objects with none scope.
For EntityManager, this is associated with persistence context. It is used to create and remove persistent entity instances, to find entities by their primary key identity, and to query over all entities. For more, refer to the JPA (Java Persistence API) Specification, or Hibernate.
#Inject, means that the instance is injectable. They follow the infamous crase word of Depency Injection or Inversion of Control (IOC). What this basically mean, is that when the resource (in your case EntityManager entityManager is needed, the JEE container instantiates the resource for you (without you needed to instantiate it directly through e.g. a constructor, etc.).
I have no clue what #DataRepository means. Never seen it before.
I hope this helps you.
These terms are usually associated with a dependency injection framework like guice and not with java in particular.
http://code.google.com/p/google-guice/wiki/Scopes describes the various scopes that are built into guice.
By default, Guice returns a new instance each time it supplies a value. This behaviour is configurable via scopes. Scopes allow you to reuse instances: for the lifetime of an application (#Singleton), a session (#SessionScoped), or a request (#RequestScoped). Guice includes a servlet extension that defines scopes for web apps. Custom scopes can be written for other types of applications.

Refreshing/replacing beans in the ApplicationContext. Possible or am I missing the point?

First off, I think I'm trying to use Spring incorrectly, but confirmation would be appreciated.
I am trying to reset a single bean in mid-application. My initial configuration works just fine.
My scenario
1 Insurance Claim bean (session
scope)
1 Claim details bean which is a
multiactionController
(getClaim&setClaim enabled, prototype
scope)
1 Claimant details bean which is a
multiactionController
(getClaim&setClaim enabled, prototype
scope)
1 Submit claim bean which is a
multiactionController
(getClaim&setClaim enabled, prototype
scope).
My application is more complex than this, but for the sake of providing a clear example I wont describe the whole thing.
The first two controllers are used to set various properties of the claim, validate etc.
The third writes a claim to the database. THEN I want it to reset the bean. However I can't just say claim=new Claim() in SubmitClaimController.OnSubmit() as the ApplicationContext keeps its reference to the old Claim.
I could just create a method Claim.clear(), but that feels like the wrong approach. However, I can't see anything like ApplicationContext.destroyBean(beanname) or ApplicationContext.createBean().
I do not want to refresh the entire ApplicationContext as I will have other beans I want to keep alive throughout the session.
Thanks in advance.
I don't think the Claim object should be Spring-managed. It's really not injected; sounds like it should be bound from the request sent into the controller and passed to the service for processing. If you put a Claim into session scope, you need to invalidate the session when the transaction is done or if the session times out.
By the way, I see you mention three controllers, but no service. You should have a service layer, and controllers should not deal with DAOs or persistence.
You can change the scope of a bean. Default is singleton which is sometimes not appropriate in web contexts. You can change it to be session scoped by adding for example
the attribute scope="session"
and the child <aop:scoped-proxy proxy-target-class="false"/>
to the bean definition.
I am working with 3.0M4, btw, but I would expect it to be in earlier versions, as well, as it's a very important functionality. Have a look at:
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ch03s05.html
Cheers!

Categories