Injecting using request scope and threads - java

I have some bussines classes that get injected some dependencies that are provided using servlet request scope.
The problem is that I want to use that bussines classes in some threads that outlive the servlet request.
Whats the most transparent way to do that?

If you are using Spring (which, by the terms you use to describe your problem, you seem to be using), you can use an AOP scoped-proxy for your request-scoped object, and inject this proxy into the objects that outlive the servlet request. The scoped-proxy will take care of using the right instance everytime you access it.

Well,
I'm not sure if I get your problem. I think there is problem with architecture itself, but however this could help you:
Guice module
bind(Bussines.class).annotatedWith(Names.named("request")).to(Bussines.class).in(RequestScoped.class);
bind(Bussines.class).annotatedWith(Names.named("session")).to(Bussines.class).in(SessionScoped.class);
bind(Bussines.class).annotatedWith(Names.named("application")).to(Bussines.class).asEagerSingleton();
Usage
#Inject #Named("request")
private Bussines bussines; //inject a new bussines class every request
#Inject #Named("session")
private Bussines bussines; //inject a new bussines class each session
//This is little bit tricky, cuz Bussines is stored in session. In Stage.PRODUCTION are all injection created eagerly and there is no session at injection time. Session binding should be done in lazy way - inject provider and call bussinesProvider.get() when em is needed;
#Inject #Named("application")
private Bussines bussines; //inject singleton
Also you can use Private modules to bind different scoped objects to a class. Don't forget to expose it.

I see 3 options:
You could add the information you need to an object that has a larger scope like application or session scope
You could persist the information in a file or the database and look it up later
You could save the information on the thread or use a thread scope: http://code.google.com/p/google-guice/issues/detail?id=114

I may not suggest you directly use or inject HttpServletRequest at business bean which is not in request scope . because this will break up app layers. if you want the value from the request or request header, then you can pass value to object to pass to the business layer, because otherwise, it is not secure, and generally, app will apply some security interceptor at that request scope , but if you directly inject to other layer , then it jump over and the interceptor may be skipped... this way also break the encapsulation and obvious is anti-pattern.

Related

EJB : understanding how container choose bean

I'm trying to understand how statefull beans works (I read the theoretical part and I know the difference between statfull and statelss beans ...), for that reason I created a statefull bean and a rest API to access it.
I find out that the container create/instantiate a new bean for every request.
then I used a servlet to access the same statfull bean, and this time the container crate just one bean that serves all requests.
So my questions are :
why does the container create many bean for rest API ?? I know that it consider each request as a separate client but how it knows, since rest API or servlet are accessed using http requests??
why it consider request when it comes from servlet as one client?? (therefor it create one bean)
in my case (doing test localy) how to force the container to create more beans (how to simulate more than one client) when using servlet.
Thank you in advance
I checked the specs, but I could not find something about this. But that seems reasonable:
Somebody must take care about the SFSB instance, closing it when done.
When exposing an EJB business method of a SFSB as REST service, a generic servlet is used. The only scope available is the request scope of a single (stateless) HTTP call, so after the call is done, the generic servlet should close the SFSB.
The servlet has an explicit lifecycle. An injected EJB is create during initialisation of the servlet and can be closed on destroy.
You can lookup new SFSB instances with every HTTP session created, using the session context for subsequent calls on this session and closing the SFSB when the matching session is closed.

Jersey 2 - Request scoped binding vs Singleton binding

I'm learning Jersey and trying to build a rest api. But I'm having a hard time understanding the difference between various bindings - bind() , AbstractBinder(), bindFactory() and also the scopes - RequestScoped , Singleton and PerLookup. What are the differences between them and when to use which one?
e.g. Say I have some request specific data passed into the request header. I want to use this data multiple times (say in resource classes, DAOs etc) during the request processing. What I figured is that I'll use a request filter and extract the data using the ContainerRequestContext and store it to some class. But i'm not able to figure out how to bind this class so that I can access it later. Which binding to use in this case?
bind() and bindFactory() are methods in the AbstractBinder class that you use to bind your services in the registry. The AbstractBinder is what you register with Jersey so that it knows to configure all your bindings. You use bind() to bind the service itself. You use bindFactory() to bind the service using a Factory (or Supplier in 2.26+) to create the service.
RequestScoped means that the service is scoped to the request, meaning that it will be the same instance for the lifetime of the request. You would use this scope when the service is dependent on information tied to a request, like request headers.
Singleton scope means that there will only be one instance of the service for the lifetime of the application. You would use this scope when the service can safely be used at anytime without being tied to any request.
PerLookup means that a new instance of the service will be created every time it is looked up, either directly through the ServiceLocator (or InjectionManager in 2.26+) or via an #Inject (or other injection) annotation. Even though this is the default scope, the RequestScope and Singleton scope would be more appropriate for most of the use cases in the context of a Jersey application.
For your use case where you want to get information from the request context and use it in the service, you would use a RequestScoped service and use a bindFactory() with a Factory (or Supplier in 2.26+) and inject the request context into the Factory and use the context to create your service. You can see more explanation in How to inject an object into jersey request context?. If you are using Jersey 2.26+, you'll also want to read Jersey 2.26: register #Inject in ResourceConfig bindFactory cannot convert Factory to Supplier

Spring run method before starting endpoints

Is it possible to call some method while Spring is being initialized - after database connection is started but before #RestController endpoints are started (available to send requests)?
I need to send some database requests (using JpaRepository) before REST endpoints are ready.
I tried to find similiar post but I wasn't able to. I found annotation #PostConstruct or interfaces CommandLineRunner and ApplicationListener<ContextRefreshedEvent> but I think all of then are called after endpoints are started? Or am I wrong?
#PostConstruct is called after a bean is completely constructed but before it is "put into service"--which, in the case of a controller, means before it starts serving requests. (In the case of a service bean, this would mean before it is wired into any other beans.)
Note that it's best to use constructor injection to provide dependencies to your bean, but it may still be sensible to do database queries in #PostConstruct to avoid heavy operations in an actual constructor.

Is there a "Spring 3 MVC way" to listen to the end session event?

I would like to delete some temporal files when user session finishes. The information associated with the files is stored in an object annotated with #SessionAttributes.
The only way I've found to deal with this is creating an HttpSessionListener.
Is there a higher level, simplified, Springy way to listen to the session end event where I could easily get my annotated object?
You most likely will need to create a HttpSessionListener.
Another stackoverflow answer:
Detect session timeout in Spring 3/Spring Security 2.0.5
Also and example on how to load spring beans into it:
http://www.mkyong.com/spring/spring-how-to-do-dependency-injection-in-your-session-listener/
Two options to use HttpSessionListener with spring beans:
The first is to use WebApplicationContextUtils.getRequiredApplicationContext(servletContext) to obtain the servlet context. From there you have two sub-options:
use getBean(..)
If you want to use #Autowired / #Inject use getAutowireCapablyBeanFactory().autowireBean(this). You will have to do this only once (check if the fields are null), because the listener is singleton.
The second option is to use AspectJ and #Configurable on the listener.
Not directly related, but might be an interesting project to look at.
https://github.com/shawnmclean/Idle.js
Session deletion typically happens on the server side, when the session expires (usually 30mn). The project above allows to detect user behaviors in the front end.

#Autowired HttpServletResponse

I'm looking for a way to autowire HttpServletResponse. It doesn't work with spring out of the box, but I've found this description. This works but is sort of annoying, in that spring obviously has a mechanism to make objects request scoped (i.e. HttpServletRequest) and this seems to be a hack bolted on top.
Is there a way to hook into the same mechanism that spring uses for HttpServletRequest? And, any idea why spring team decided to only make HttpServletRequest autowire capable (and excluded HttpServletResponse)?
Perhaps there is some workaround, but it's not that obvious, because it's not the way it's meant to be. Spring MVC is meant to have singleton #Controller beans that provide #RequestMapping methods which take the request and response as arguments.
If you need the response in another place (the service layer) - don't do it. The response should not go beyond the web (controller) layer.
To inject the response, you need:
- to store the response in a ThreadLocal
- to make a factory bean that returns the current response
About the example code you showed - I'm not sure if you are not going to need the factory bean to return a proxy (implementing HttpServletResponse), which in turn to return the current response. And it gets rather complicated.
But ultimately - you should not do that. If you need to intercept multiple controller invocations, use an mvc-interceptor. If you really need to use an aspect, you can get the response if it is passed as argument to the intercepted method.
Can you simply include the request in the method handle?
#RequestMapping(method=Method.GET, value="myUrl")
public String doGet(HttpServletResponse response){//spring will put the response in for you
...
}

Categories

Resources