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.
Related
I am trying to perform logging of all HTTP outbound requests from my application. However, I need the HTTP interceptor to have access to some meta-data of the HTTP calls. This data is set manually for each separate type of HTTP call in the app logic itself. Now, there are two apporaches I have found so far to pass this data on to the interceptor:
Include this metadata in a temporary HTTP header, log it when the call is intercepted, remove the header, make the call
Store the data in a static ThreadLocal variable, retrieve it in the interceptor and clear the ThreadLocal storage
Although both these methods work fine, there are some reservations I have regarding both methods. For the first method, it seems unwise to alter the HTTP request itself as, in case, the interceptor is not working/not being used, the metadata will be passed on to the remote server. For the second method, the use of ThreadLocal comes associated with problems of heap memory management as too many threads might eat up heap space.
Is there any other standard/recommended method to approach this problem? If not, which of the above mentioned methods would be better suited at addressing this problem statement?
An alternative method in Spring is to have a Bean with bean-scope set as "Request". Singleton scope beans are not thread-safe, however, with a Request scope, a Bean is established only within the context of a single HTTP-Request and as such. Such a Bean is instanitated at the start of an HTTP request and its state persists the entire duration of just that HTTP request. The syntax for this is:
#Bean
#Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public HelloMessageGenerator requestScopedBean() {
return new HelloMessageGenerator();
}
or, alternatively, a shorter version of the same code:
#Bean
#RequestScope
public ScopedBeanClass requestScopedBean() {
return new ScopedBeanClass();
}
The ScopedBeanClass may now be used to set and read values in a thread safe manner at any point during the lifetime of a single HTTP Request after which the Bean is cleared/reset in the next request (possibly from a concurrent Thread)
Request scope is one of 4 web-aware scopes that can be used. The other scopes are: Session Scope, Application Scope and WebSocket Scope
More info on these scopes is present here
Please try spring cloud zuul. In its zuulFilter, you can log every request, then re-dispatch request to target. The spring cloud gateway has same effect.
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.
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
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.
I am trying to figure out how to create a stateless spring bean that wraps a group of calls to salesforce web service API. My understanding is that the process for calling salesforce is something like this:
Call the login service to Log into salesforce
Make a series of service calls
Call the logout
To have a stateless wrapper it seems right pattern is to have each method in the bean perform all three steps above. e.g. (pseudocode)
binding.login();
binding.upsert(….);
binding.upsert(….);
binding.logout();
Is this a good practice? It seems it would be a costly way just to keep the bean stateless. Would it be preferable in this instance to make the bean request scope?
I agree with Anup, you should take a look at the sfdc wsc.
If you want go entirely stateless you will need to know the following things about a salesforce connection.
every action must have an endpoint url, something like na6.salesforce.com or na7.salesforce.com
every action must have a valid SID(session id) for the action to complete.
When you login to salesforce the original endpoint is login.salesforce.com and if you are sucessfull you will be returned a valid endpoint(na6.salesforce.com) and a SID.
You can then drop that endpoint/sid into a singleton and share it with as many spring beans as you want. In each bean you will need to create a new SoapBindingStub and set the endpoint and sid before you execute an insert/upsert/update/etc. action.
That sid will expire after a period of inactivity (anywhere from 30-120 minutes depending upon setting) so you should catch any exceptions and relogin using the singleton object.
Dont worry about two beans casuing the singleton relogin at the same time because salesforce will return the sames sid to both.
Have you tried SFDC WSC library? It's easy to use, and fits the use case that you are trying to accomplish.