Injecting a bean with #Autowired not working in Soap Handler Issue? - java

Hi I have a SOAP Handler class which is handling the logging for request which we get for a Webservice API. I am trying to insert this request in DB inside SOAP Handler. I have created DAOs which i m trying to inject through #Autowired annotation which are used to insert request in DB. But it is giving me Null Pointer Exception instead. Why does #Autowired not work here while it works perfectly well my #Service classes.

Was your SOAP Handler been instanciated by Spring ?
Your #Service classes are read and instanciated by Spring at DI Container initialization, so the #Autowired can work.
So your handler need to be instancied by Spring to be managed (with a #Component-like annotation, for example). If it need to be instanciated by a Java EE container, you should consider extending SpringBeanAutowiringSupport
Regards

Related

Refreshing #Resource and #Autowired bean at Runtime

I have one bean which is define in the SpringConfiguration and which gets initialised at the startup.
This bean(Map) is populated by querying the database at startup.
Now the database gets update frequently and I have implemented the ApplicationListener and was trying to implement a cache using TimerTask.
The code of timertask runs fine and in that i am accessing the bean using ApplicationContext but not able to refresh/reinitialize the bean with the new database results.
The #Resource and #Autowired beans still shows the old value.
I want to refresh/Reinitialize the #Autowired / #Resource bean at Runtime. Please advise
If you are using an ORM it should handle it for you.
Otherwise, if you are doing it on you own, you can annotate the bean with #RefreshScope and when you detect a change (wherever method you are using like cron or listener) then just refresh the context from the actuator like:
http://localhost:8080/actuator/refresh
Cheers!
pd: Actuator should be enabled and accesible.

Spring #Service vs Object Service

I have a question about #Service in spring, but i didn't find any response about it.
Situation :
I have a web application with #RestController using spring
Now for my service layer, I saw on some project two way of processing
#Service on service class and #Autowired on controller class (Create a bean that is a singleton excepted if we change the scope)
Create a object like a service
MyService service = new MySerivce()
So my questions are :
Create a object each time for each call of controller will not be a issue for memory ? If i create a load test (with Apache Jmeter) and send 1000 requests, it will create 1000 object my service so could be a problem no ?
Create a singleton with #Service will not be a issue for memory but, how spring will handle 1000 requests on 1 seconds for example. Will he push requests on a sort of queue and execute one at a time ?
What is the best practice for Service declaration and why ?
Thank in advance for any response
The whole point of dependency injection (using annotations such as #Autowired and #Service, #Component etc.) is to let Spring manage instances of service classes for you, instead of manually creating an instance with new MyService() each time you need it.
Letting Spring manage service class instances (and other Spring beans) has a number of advantages. For example, it makes it a lot easier to replace a service with a different implementation; you only need to change the Spring configuration for that. Also, it makes it easy to inject a mock version of a service for unit testing. Replacing real services with mocks would be really hard if the class you are trying to test is directly instantiating a specific implementation of the service class using new MyService().
how spring will handle 1000 requests on 1 seconds for example. Will he push requests on a sort of queue and execute one at a time ?
No. Calling a method on a service is just like any other method call. There is no invisible queue and there is also no reason why that would be necessary, as long as the methods in the service are thread-safe.
What is the best practice for Service declaration and why ?
When you use Spring, use Spring's dependency injection and never instantiate service classes using new in your code.
Spring Controller uses IOC mechanism like where Singleton objects are created, like in example you described #Service,
Application Server manages requests client, It uses thread pooling to handle request and generated or use same thread for request or response,
Spring applications are it self uses container mechanism where objects are created using #Service and #Autowired annotations.
When ever we are using #Service, this means we are telling spring
to create a object of that class and keep in Spring container, By
default its Singleton. Wherever we are using #Autowired then spring
handover that object to the Service/caller.
Whenever we are calling MyService service = new MySerivce()
java
creates new object of MyService every time. If that service called
1000 times then MyService object will get created 1000 times, and Spring
has no control on this.
Best Practice is :
Use Spring #Service annotation to create object and use annotation #Autowired to get that class object.
Handling 1000 Requests
Spring will not create 1000 new service object, it will use same service object (which is autowired) if object scope is Singleton which is default scope
but incase of Prototype, it is same as creating a object with new keyword.
SO in this case it will create 1000 objects.
For handling huge requests we need to make thread safe, pooling separately, in this case Spring will use its container pooling which is not very efficient.

Failing to #AutoWire a member in a #WebServlet

I can't seem to get my servlet's fields to #AutoWire; they end up null. I have a pure annotation-configured webapp (no XML files). My servlet looks like this:
#WebServlet("/service")
public
class
SatDBHessianServlet
extends HttpServlet
{
#Autowired protected NewsItemDAO mNewsItemDAO;
}
Other #AutoWired things seem to work fine, both #Service objects and #Repository objects. But not this one, and I can't figure out why. I even tried adding its package to the ComponentScan(basePackages) list for my other classes.
Additional Info:
I added the following to my servlet’s init() method, and everything seemed to wire up properly, but I'm confused as to why Spring can't wire it up without that.
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, inConfig.getServletContext());
Servlet are web components that are not being created by Spring container, based on that lifecycle is not managed by the container and a lot of stuff that spring provides such as autowired or aspect can not run from them.
You need to indicate to the spring container that a component was created outside of IoC container and need to be part of it.
And as the API said SpringBeanAutowiringSupport is for:
Convenient base class for self-autowiring classes that gets
constructed within a Spring-based web application
This generic servlet base class has no dependency on the Spring ApplicationContext concept.
There is another way to indicate servlets being created by spring container using an interface
Spring MVC uses the DispatcherServlet for handling all requests in a Servlet environment.
The DispatcherServlet accordingly forwards the requests to the appropriate #Controller class (if any) based on the #RequestMapping on that class and/or it's methods.
What is happening in your Servlet is that it is not managed by Spring (but by the Servlet container) and there for no injection of dependencies is occurring.

Inject a singleton in an ExceptionMapper

I have an ExceptionMapper defined as following
#Provider
public class MyExceptionMapper implements ExceptionMapper<Throwable> {
#Inject
private Manager myManager;
#Override
public Response toResponse(Throwable exception) {
// My implementation
}
}
Deploying this code on glassfish 4 results with exception:
org.glassfish.hk2.api.UnsatisfiedDependencyException:
There was no object available for injection at
Injectee(requiredType=Manager,parent=MyExceptionMapper,qualifiers {}),position=-1,optional=false,self=false,unqualified=null,955636053)
When I use #Context instead of #Inject I do not see the exception but myManager is null
I tried making MyManager as #ManagedBean, #Singleton or an EJB (Stateless, Singleton) and non works
In JEE6 (with glassfish 3) you have to add
#javax.annotation.ManagedBean
to the provider implementation. Possibly this works also for Glassfish 4
As far as I know, this issues comes from the following. CDI is not in place to manage the dependencies of restful services and providers by default. But when adding #ManagedBean you enable CDI to create the instance.
Here is an example where I introduced CDI to a restful service using jersey.
You can follow the updates regarding this issue here https://java.net/jira/browse/JERSEY-2393
You could use OmniFaces Beans to get a CDI managed bean instance in your ExceptionMapper:
Beans.getInstance(Bean.class)
I'm using this with #javax.ejb.Stateless beans containing #javax.persistence.PersistenceContext.

How to get a prototype bean for a singleton Controller in Spring?

I'm using annotation configuration and I currently cannot use request scope for my controller, but I need one of the bean that controller uses to be a prototype. So I figured the best way would be getting prototypes for a singleton controller via method injection.
But then I realized that Spring's method injection needs an abstract class so that I couldn't use my annotation configuration ...
Could please anybody tell me how to do that ? It seems to me that it is very common scenario, but currently it can be realized only via "request scope" of controller.
Or I'd have to make my controller ApplicationContextAware and get the bean from context. But can annotation-config #Controller be ApplicationContextAware ?
You can simply #Inject ApplicationContext ctx, but you need your other bean to be defined in the child context (dispatcher-servlet.xml) (you need that anyway). And then you can look it up.
There is no way to define lookup-method injection with annotations currently. There is an open issue about that. So for this particular controller you can use xml configuration to define the lookup-method.

Categories