Controller beanPostProcessor spring - not singleton? - java

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

Related

Restricting injection from a bean definition, not from the autowiring end (bean not injectable implictly)

Is there any annotation/trick in Spring that marks a #Configuration #Bean as injectable only on strictly qualified #Autowireds?
I'd like my bean to be qualified in a way that only those that specifically call for its #Qualifer can inject it. It's indeed a mechanism for controlling where is it going to be able to be autowired, with no ambiguity nor arbitrary decisions depending on available beans in the context.
So my bean would never be autowired as a side-effect out-of-my control without me actively marking the injecting as expecting it
You can control bean creation with #Conditional annotation.
Also if you need real control of using bean you can create some annotation like #ConroledByQualifer and use this annotation instead of standard spring component annotation , or extension for one (like service , repository .... ) .
So spring can't process it for autowired as one don't know how to handling it.
You need add custom BeanPostProcessor that will work with #ConroledByQualifer - create it and inject. So your custom bean will be processed only by BeanPostProcessor for #ConroledByQualifer and not custom spring BeanPostProcessors.

How to get Spring MVC Controller to load lazily?

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).

JSF and CDI with inputFile component

I made a simple xhtml page for upload file by using <h:inputFile> component. And everything works fine. And in managed bean I used dependency injection for the Logger. I used a factory class and createLogger() method in, to enable injection for object of Logger class.
Everything is ok but, nothing works without a #Model annotation in managed bean.
Can somebody explain the meaning of the #Model annotation.
I can not find on internet proper explanation. A founded explanation of other annotation like as #Session, #Request, #Application etc.
What does the #Model annotation do?
Hej vmaric,
#Model == #RequestScoped + #Named
It exposes the Backing Bean directly to your JSF 2 or JSP and its context will be destroyed after the end of the servlet request.
So it should not be used for entities.
Here is a hint from the Weld Reference Guide:
Notice the controller bean is request-scoped and named. Since this combination is so common in web applications, there's a built-in annotation for it in CDI that we could have used as a shorthand. When the (stereotype) annotation #Model is declared on a class, it creates a request-scoped and named bean.

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.

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