Spring bean creation - spring

Is it possible to create to bean with same id with same class with different property in spring ? Like:
<bean id ="a" class= "com.tofek.A"
<property message = "khan"/>
</bean>
<bean id = "a" class = "com.tofek.A"
<property message="tofek"/>
</bean>
As per my understanding it will create, but while fetching the bean using getBean() method it will give exception like NoBeanDefinitionFoundException.
Please correct my understanding if I'm wrong?

Make sure your spring context is loaded sucessfully.
Answering your question. You can have two identical bean definitions in two different sprintContext configurations.
The bean from second context will override bean created by first one.
For example :
context1.xml
<bean id="bean1" class="org.springframework.beans.TestBean"/>
context2.xml
<bean id="bean1" class="org.springframework.beans.TestBean"/>
then, the bean from context2.xml will override bean created by contex1.xml.
It of course depends on order of creating spring contexts. The laters overrides the ones made before.
You can use getBean() to fetch bean by type or name. In this case, both bean have same id's and types, the spring wouldn't know which one you want to fetch.

Related

using property-placeholder with beanfactory in spring

With below XML configuration
<context:property-placeholder location="constants.properties"/>
<bean id="MyDBDetails"
class="itsmine.springcore.MyDBDetails" scope="singleton">
<property name="fName" value="${fName}" />
<property name="lName" value="${lName}" />
<property name="age" value="${age}" />
</bean>
I created a bean in my main using below 2 options:
1) using ClassPathXmlApplicationContext
2) using bean factor
The dynamic values got set when bean created using ClassPathXmlApplicationContext, but not when created using bean factory.
Could you please suggest how to make it work using bean factory ?
Thanks in advance.
When using XML declaration for bean properties, the property-placeholder is registered as a Bean Factory Post Processor for the IoC container, thus you will have the properties values available.
However, when instantiating beans programatically through a BeanFactory, this factory won't be aware of the properties values unless your configure a `` as its post processor:
BeanFactory factory = /* your factory initialized */;
PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("constants.properties"));
cfg.postProcessBeanFactory(factory);
EDIT
Note that the org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#setLocation accepts a org.springframework.core.io.Resource as its argument, i.e. you can use any of the its concrete sub-implementation depending on your needs:
org.springframework.core.io.FileSystemResource: An implementation supporting file handles.
org.springframework.core.io.ClassPathResource: An implementation for classpath resources.
org.springframework.core.io.InputStreamResource: An implementation for an InputStream...

Spring bean scope : singleton and Prototype

Case 1 : Suppose we are injecting singleton bean inside prototype bean then how many instances will be created if we call prototype bean.
Consider the scenario :-
<bean id="a" class="A" scope="prototype">
<property name="b" ref="b">
</bean>
<bean id="b" class="B">
Case 2: Suppose we are injecting Prototype bean inside singleton bean then how many instances will be created if we call singleton bean.
Consider the scenario :-
<bean id="a" class="A" >
<property name="b" ref="b">
</bean>
<bean id="b" class="B" scope="prototype">
I am answering a part of your question.
Case2: Singleton beans with prototype-bean dependencies
With this configuration, it is expected that when ever you fetch A from application context, it will be wired with a new B as we declared the B bean is of prototype scope. But this will not happen.
When the application context gets initialized, it sees that A is a singleton bean and initializes it to the context after wiring it with all the dependencies set. So from then onwards when we request context for A, it return the same bean every time, So you will also get the same B everytime.
You can solve/overcome this by using Lookup method injection. Refer this article.
The singleton bean will always refer to the same object. The prototype will have as many instances created as many times that bean is referenced. The use cases you provided don't change this paradigm.

Spring Scope as singleton working

In below example I am not very much clear as of what is happening
<bean id="triangle" class="com.mkyong.Triangle" scope="singleton">
<property name ="pt1" ref ="point1" />
<property name ="pt2" ref ="point2"/>
<property name ="pt3" ref ="point3"/>
</bean>
<bean id="triangle1" class="com.mkyong.Triangle" scope="singleton">
<property name ="pt1" ref ="point1" />
<property name ="pt2" ref ="point2"/>
<property name ="pt3" ref ="point3"/>
</bean>
I am seeing two instances of Triangle Object. How Internally Spring handle this?
I know Spring is using Reflection. What's the point in using singleton because its behaving like prototype(giving me two Triangle object). If the concept of scope lies for a same id(either triangle or triangle1) then it should be defined as single object per id per spring container per classloader per jvm instead of single object per spring container per classloader per jvm
Defining a bean as singleton does not mean that it will only be one instance of that class. The singleton scope applies to the bean definition, so you will have two singleton beans of type triangle.
It will have one single instance for triangle1 or another single instance for triangle2.
When a bean is a singleton, only one shared instance of the bean will
be managed, and all requests for beans with an id or ids matching that
bean definition will result in that one specific bean instance being
returned by the Spring container.
You can check more information at http://static.springsource.org/spring/docs/3.0.0.M3/reference/html/ch04s04.html#beans-factory-scopes-singleton

overriding bean configuration in spring

Let's say I have two modules. One is core and another is core dependent implementation module.
Core is a jar file for that dependent implementation module war.
In the core I have a bean defined like
<bean id="x" class="com.pokuri.X">
<property name="y" ref="y"/>
<property name="z" ref="z"/>
</bean>
And that class has a method as follows
public class X{
public void doSomeJob(){
.......
}
}
this method is being called from some core classes. Now I need to alter the logic in that doSomeJob() method of X as per my core dependent implementation. So, I create a class like this
public class ExtX extends X{
#override
public void doSomeJob(){
// changed logic
}
}
and defined the bean with same id in another application context xml file like this.
<bean id="x" class="com.pokuri.ExtX">
<property name="y" ref="y"/>
<property name="z" ref="z"/>
</bean>
and we are building application context using contextConfigLocation context parameter in web.xml specifying value as classpath:springfolder.
But in the core logic I am getting core bean instance only(i.e X instance) not ExtX. How can we override that bean definition and let system start using new extend bean definition?
And I heard that with same ID in different application context files will override first loaded bean definition with later loaded bean definition. Is there any priority kind of attribute on bean definition to let ApplicationContext use highest priority one to consider over low priority one when beans with same ID were found.
One way of overriding the bean definition is what you have indicated - to define it with the same id multiple times and the last bean definition with the same id is the one which takes effect. So if you ensure that ExtX is the last one loaded up, it should just work, and to ensure this you can do this in your war file, instead of loading up by saying classpath:springfolder, you can explicitly import the core configuration in your war's Spring config file and then override the bean this way:
<import resource="core-resource.xml"/>
<bean id="x" class="com.pokuri.ExtX">
<property name="y" ref="y"/>
<property name="z" ref="z"/>
</bean>
This will ensure that your overridden bean is the one which takes effect.
There is no priority/order field that you can make use of here though - if you want you can load up all bean definitions of a type by providing Map<String,X> as a parameter, and sort it by expecting an order property and use it that way, but there is lot more work to it.
A second approach is described here: Overriding the bean defined in parent context in a child context

Spring - List references a DOA method to get its values

I am brand new to spring and I am trying to write my first spring application.
I have set up a DOA class that accesses the DB and pulls a list of values. I would like to reference those values in a bean definition.
For Example:
I have DAO class called "JdbcDataDAO" that contains a method getValues() - I would like to reference the values in a standalone list in my bean definitions
Here is what I have:
<bean id="dataDAO" class="dao.impl.JdbcDataDAO">
<property name="dataSource" ref="dataSource"/>
</bean>
<util:list id="myList" list-class="java.util.List">
<value>#{dataDAO.values}</value>
</util:list>
But when I retrieve the bean "myList", it contains "#{dataDAO.values}" and not the values
Any help would be appreciated - Thanks
Note sure if you can do this with SpEL. And it doesn't look good anyway - you are mixing infrastructure/configuration with business logic.
You can have a factory-bean or a #Configuration class with #Bean methods where you can inject the DAO and programatically populate the list.
You can also have a BeanPostProcessor that takes all List beans an fills them with whatever you want.

Resources