How to get Spring MVC Controller to load lazily? - java

I am not able to get Spring MVC Controllers to lazy load.
I have tried the solution mentioned in Does Spring MVC initialize all controllers on start up??
Here is my code:
app-servlet.xml
<context:component-scan base-package="com.mvc.controller">
AssetController.java
#Lazy(value=true)
#Controller
#RequestMapping("/api/asset")
public class AssetController{
#Autowired
private AssetService assetService;
What am I missing here?
Spring v3.0.7

#RequestMapping annotation makes controller to be initialized eagerly despite the fact that it is also annotated with #Lazy(value=true).
In your case, removing #RequestMapping annotation should make the controller initialize lazily. Though I do not know if it is possible to use #RequestMapping annotation and have that controller load lazily, I did not manage to achieve it (solved my issue without making the controller load lazily, but that is out of scope of this question).

Related

Can we use #autowired on an entity object in spring?

I have a entity class called Customer, I am using this entity object in another class to set the data. When I use this object below like
#Autowired
Customer customer
Spring is complaining that please configure the bean in your classes.
Can we use auto wiring with entity objects?
You can only autowire only those beans whose life-cycle are managed by Spring IoC container.
These beans are defined in xml form with </bean> tag, or with some special annotations like #Bean, #Component, #Service, #Repository etc.
On the other hand,
in simple terms, entities are some java objects that you will need to create, update by yourself according to your business logic and save/update/remove them in/from DB. Their life-cycle cannot be managed by Spring IoC container.
So, you should never feel like you need to autowire an entity if you are doing it right!
In fact, Spring support #Autowire only for Spring Beans. A java class becomes Spring Bean only when it is created by Spring, otherwise it is not.
A workaround might be to annotate your class with #Configurable but you would have to use AspectJ
Please look in the Spring documentations on how to use #Configurable
Also, I wonder why you would autowire an entity class ?
I would warn you not to mix Spring Bean and JPA entities in one class/usecase because:
Spring Beans are instantiated and managed by Spring
Entities are managed by JPA provider
If you mean JPAs #Entity-annotation, Spring is simply telling you, that there isn't a bean in its context.
On startup/runtime classes in the application will be scanned and each class annotated with spring annotations like #Component, #Service etc. will be instantiated as beans and put into a global context (Spring applicationcontext).
This context is then used to lookup and inject those beans into other beans when #Autowired is found during scanning.
Opposed to this, #Entity is used during the creation of the Persistence-Context of JPA (as far as I remember) which isn't aware of Spring and it's context.
Most of the solutions to make both contexts aware of each other a mostly a little bit hacky.

Controller beanPostProcessor spring - not singleton?

I have a custom beanPostProcessor that is supposed to do some logic with spring controllers.
I found out that it behaves funny. When I sysout controller bean in my post processor it says:
...controller.MassUploadController#743479ce
but when I call sysout(this) from controller request itself it is a different instance:
...controller.MassUploadController#58469848
So any changes I perform to controller instance in beanPostProcessor are not really reflected in runtime since it is a different instance. How is that possible? It states everywhere that spring controllers are singletons!
My controllers are defined in spring with #Controller and in xml I use componentScan on controller. java package

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.

Spring mvc on application load event to load collection

I have to load something from the database to initialize a hashMap object that I want to add to a application wide variable that all my mvc controllers can access.
I won't be modifying this object, and I don't care if it can only be updated when the application reloads.
Does spring MVC have a place where I can do this and have spring manage the lifecycle also?
I know servlets has the WebListener annotation:
#WebListener
But not sure if spring has this also (wrapped in their iOc container).
I think the best place is to declare a bean like the following:
public class MyInitializingBean {
#PostConstruct
private void init() {
//do initialization here
}
}
Then you declare that bean in your xml file, if you don't like the annotation, there are non-annotation approaches for initializing a bean, but that gets executed when the spring context starts.

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