Constructors in Bean - spring

I have one small issue with creating a new bean. Basically as per request, I get some parameters, which needs to be passed to a bean. Below I am instantiating ControllerService for each request. Rather I would like it to be a bean with scope=protype. So that I get a fresh object for every request.
But then how do i set the 2 properties (kpiName, kpiInput) that I am sending via constructors in the bean??
#Autowired
#Qualifier("serviceManager")
Cleanser serviceManager;
#RequestMapping(method = RequestMethod.POST)
public #ResponseBody
String getKPIResult(#RequestParam("kpiName") String kpiName,
#RequestParam("kpiInput") String kpiInput) {
return serviceManager.checkAndExecute(new ControllerService(kpiName, kpiInput));
}

In situations like this where you're going against the grain of Spring, I'd suggest that perhaps you're doing something in a way that's not considered best practice. Without more context it's hard to see though.
Spring Social uses a request scope bean to embody a repository for a specific user. I've now idea why as it's a horribly inefficient way of doing things, and much less understandable IMHO.
<bean id="connectionRepository" factory-method="createConnectionRepository"
factory-bean="usersConnectionRepository" scope="request">
<constructor-arg
value="#{T(org.springframework.security.core.context.SecurityContextHolder).getContext().getAuthentication().getPrincipal()}" />
<aop:scoped-proxy proxy-target-class="false" />
</bean>
You can see here the use of factory-bean and factory-method to declare a class/method to call when wanting an instance of your class. The constructor argument is passed using SpEL. I'm not quite sure how you'd achieve this with Spring MVC responding to web requests, but I'm fairly sure you could use Spring Integration to pass a message and use SpEL to grab headers/payload form that message to pass to the constructor.
Again though, I'd really question your design pattern here - a more usual SOA idiom is to create services on startup, and have them as stateless as possible from there-on in, rather than create an instance with specific state for each request. Best of luck!

Don't. The Controller as it's intended in Spring MVC is largely derived from the old Java servlet, which should be stateless by specification.
In fact, Controller-objects are hard-cached inside the handler mapping framework and not fetched from the bean context on each request. Setting scope to "prototype" would, effectively, do nothing as the handler (controller) is really only gotten once.

Related

Single spring bean with two different ids in same xml(application context)

If we create a new another bean with different id in the same xml for the same class, will spring produce another singleton bean(in same ApplicationContext)?
As per my understanding there should be only one instance of the bean in single ApplicationContext.
Below example-
<bean id="bean1" class="com.myCompany.myPackage.MyClass" scope="singleton" />
<bean id="bean2" class="com.myCompany.myPackage.MyClass" scope="singleton" />
To keep it short: No, the singleton only says that you'll have: "one shared instance, which will be returned by all calls to getBean with the given id" (that's what the documentation states).
So, you can do any number of calls to application context and obtain "bean1" and you'll always get the same instance, but if you call by "bean2" id, you'll get another instance.
The "singleton" says that you'll have only one object. Now in a non-Spring application, you'll have it usually per JVM. But in spring application, let the framework manage this. So usually you'll want to define only one class like "MyClass" with a scope singleton.
When dependency management container (Spring in this case) manages singletons, it has a lot of advantages over the 'regular' singleton. Just to name a few:
Much easier to test
You always know when the object is created and when it becomes subject to garbage collector
No static code (the Spring driven singleton is just a regular bean with no statics)
But in general it's not directly related to your question.
I did have this same question just in a different context of Spring's singleton vs. Java's singleton and I found this answer provided by 'Dexter' in this link more subtle and easy to understand.
Also, this blog here provides a perfect example for the same which is backed by the official spring documentation for better-detailed understanding.
Hope these pointers help. Thanks.

Spring web app controller field scope

I am experiencing some conceptional difficulty with the scope of some beans referenced in controllers. I have checked a lot of related questions in file and still not sure. Could someone please help me clarify it?
I am numbering the questions or statements as follows to make helper easier to address my problems.
Per my understanding from the the Spring doc, in spring web application,
1) for any controller, annotated with a #Controller, if there is a private field bean, with default bean scope, this field bean will be accessed as the singleton thus susceptible to thread issue;
2) If the field bean is marked as scope=""prototype, this field bean, within this controller, will still behave like a singleton, thus being not-thread safe.
3) To make such a field bean thread safe, we have to make the bean scoped with request or session right?
The following is a simplified example related to this question:
#Controller public Class ControllerA
#Autowired private DefinedBean db;
#RequestMapping("/testPath") public ModelAndView getPathPage(){
this.db.setTitle("abc");
this.db.readReportWithTitle();
....
return new ModelAndView();
}
So in this example,
4) if the DefinedBean is defined through xml configuration with or without explicit scope of prototype, this DefinedBean will have synchronization issue, right?
5) To ensure this DefinedBean to be thread safe, we have to define it explicitly with request or Session.
On the other hand,
6) if we mark the controller itself with a scope of prototype explicitly, will it get rid of the non-thread safe issue with the DefinedBean field? My thought is no, this won't.
7) To make the field thread safe, if we are going to control at the controller level, we need to mark the controller with Scope="Request" as well, right?
Your comments are welcome and appreciated. If you can comment with "Correct" Or "Incorrect" or elaborate further to those numbered (1~7) statements, Myself and possible those who come later will appreciate more.
I think you want to leave the controller be a singleton.
Here is the spring documentation that explains how to bind beans having different scopes.
This is how you would want to define the wired bean:
<bean id="db" class="DefinedBean" scope="request">
<aop:scoped-proxy/>
</bean>
I have looked up to see how the same can be done with annotations only and I have found this.
Basically, you annotate DefinedBean with :
#Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)

Creating non-bean instances with Spring

I'm sure this has been asked a hundred times before but I can't seem to find the question so feel free to refer me to other stackoverflow answers.
What do most Spring users do for objects that are non-singleton beans that require injection? For example, I have classes like Customer where I want to instantiate a new one each time. Lets say it is an entity and I want to inject listeners to iterate through in #PreRemove or somewhere else. The usual solution is to use #Configurable but that almost seems a workaround and I was wonder if there was a more canonical way to handle these.
The only thing I can think of is to create a factory newCustomer instance method in my CustomerRepository class which IS a managed bean. Then instead of injecting listeners into Customer (the most natural place) I inject them into the CustomerRepository and specify them as an explicit constructor argument to Customer ala new Customer( injectedListeners ).
Do people tend to just use Configurable or is there a better way to inject non-singleton instances? Or do most users create a factory method as above? The entity example is just an example, I have other objects that are non-singleton, are typically new'd but require injection.
Would this be handled differently in something like Guice? How would you do it just using JSR-330 features?
You can make beans non-singletons if you like. Depends on whether you are ok with the XML:
<bean id="beanA" class="misc.BeanClass" scope="prototype">
<property ... />
</bean>
Which will give you a new instance every time. Each instance will be initialized with injected values.
You can use this annotation too:
#Scope("prototype")

Spring config and runtime separation

When using Spring it is rather cumbersome to incorporate runtime data in bean construction. While there are techniques to circumvent this separation, I have a feeling that it was put in place for a reason. My question is whether this is a known paradigm, and if there is any litterature discussing it. Personally I find that it has both advantages and drawbacks, depending on the dynamicity of the app.
You have at least five well known methods to pass runtime data to beans configuration:
Use ApplicationContextInitializer to add PropertySources to the Enviroment.
Use SPEL to inject dependencies.
Use FactoryBeans.
Use the factory-bean and factory-method attributes.
If you write the class that need the runtime data, you only need to inject the
collaborator that provide it.
For example
<bean id="requestAttributeReader" class="example.RequestAttributeReader" />
<bean id="requestInjectedBean" class="example.RequestInjectedBean" scope="request">
<property name="a" value="#{requestAttributeReader.a}" />
</bean>
Class RequestAttributeReader {
public String getA() {
return RequestContextHolder.getAttributes().getAttribute("a");
}
}
EDIT
The bean description files of an IoC container lets you to configure implementors on application beans. This is normally a static definition of the implementation classes that you want to use for a concrete configuration, so xml it's good for it.
If you need to choose an implementor based on runtime then you need to write code to choose them and then inform the container.
for example, using PropertySources and PropertyPlaceholderConfigurer:
String service = "example.NormalService";
if (BOSS_USERNAME.equals(System.getProperty("user.name")))
service = "example.BossService";
ctx.getEnvironment().getPropertySources().addFirst(new PropertiesPropertySource("service", service));
<bean id="service" class="${service}" />
The same could be done with a ServiceFactoryBean, a external ServiceFactory, SPEL and so on...
Maybe, you are interested on replacing implementations at runtime, ie changing the Service implementation in all beans that depends on when the container is already refreshed. (without destroy and refresh).
As far as I know, the framework don't provides a clear way to do it.
Sounds like you should look at spring binding, eg:
public String create(#Valid Market market, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) {
So this will take request params that match the fields in the Market object and set them in that object. It will also validated the params/object since there is the #Valid annotation.
This binding can be customised with PropertyEditors or Converters.
If the market object is annotated #Configurable, it can use #Autowired and #Value annotations to configure the bean when spring creates it.

Can i use Spring's #RequestMapping and BeanNameUrlHandlerMapping in conjuntion with each other to map a URL to method?

What I would like to do is have a common Service class which has various methods such as "search" "retriveByID" etc.
Ideally this class would consume the service parameters and populate a request object and hand off to the appropriate data source handler.
I want to instantiated a service class as a Spring bean with different request handlers depending on the domain object being searched. Then using bean BeanNameUrlHandlerMapping invoke a different Service class based on the URL.
<bean name="/sequence/*" class="org.dfci.cccb.services.SearchServiceImpl">
<property name="searchHandler">
....
My problem is that when i try to do this I can't use method level RequestMapping annotations to select the appropriate method of the service class.
#RequestMapping("*/search/")
QueryResult search(...
Alternatively is it possible to inject annotation values through bean definitions?
UPDATE
There is also a Springsource article on this topic:
http://blog.springsource.com/2008/03/23/using-a-hybrid-annotations-xml-approach-for-request-mapping-in-spring-mvc/
Was very surprised to learn that it actually works. Just remove the trailing slash:
#RequestMapping("*/search")
And this works too:
#RequestMapping("search")

Resources