Spring Core - Alias and Ids - spring

I started learning Spring today and came across a strange behavior, so seeking any expert help on the behavior. I defined a bean with an id and verified the bean is available via ApplicationContext and Bean factory. Later created more beans with different IDs but created one alias with the exact same Id of the First Bean (xml snippet below)
<!-- Beans -->
<bean id="wolf" class="com.badwolf.spring.SpringWolf">
<constructor-arg type="java.lang.String" value="wolfy" />
<constructor-arg index="1" value="20" />
</bean>
<bean id="sweetWolf" class="com.badwolf.spring.SweetWolf" />
<!-- Aliases -->
<alias name="sweetWolf" alias="wolf" />
Now in the implementation class when getting the bean using "wolf" then getting the bean associated with the "Alias". Is this intended behavior of Spring? Do Aliases take precedence over the bean definition (which seems to be the core of Spring)?
What if my project is split into teams and on integration someone has used the same id and alias and all of a sudden a portion of functionality stops working.

Firstly, there are three Spring bean terminology here, name, alias, and id.
Spring bean can have multiple names, aliases, while it can only have one unique id.
Below is reference from Spring doc
Every bean has one or more identifiers. These identifiers must be unique within the container that hosts the bean. A bean usually has only one identifier, but if it requires more than one, the extra ones can be considered aliases.
So in your case, bean with id of "wolf" has Spring-generated name ("springwolf"), while bean with id "sweetWolf" has two names, Spring-generated name("sweestWolf") and name alias("wolf") (spring-bean-names).
Related discussions for alias vs name (1, 2)
Related discussion for alias vs id (1)

Related

Spring bean creation

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.

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 Framework (V2.5) - Using actionpath in ref attribute in a bean definition

I am a pretty newcomer for Spring Framework.
This is regarding referencing another bean using ref attribute.
I have a bean definition for an action class like below.
<bean name="/abc" class="com.example.actions.Action" scope="singleton">
<property name="businessLogic" ref="/pqr"/>
</bean>
I am trying to inject another bean into this bean using ref attribute (ie "/pqr").
<bean name="/pqr" class="com.example.businesslogic.PqrBL" scope="prototype" />
Now my question how normal is it to use name="/pqr" kind of a notation for a bean which is not a definition for some action class ? By convention is it an acceptable normal scenario ?
PS: please let me know if information provided is incomplete or the question is not clear.
Thanks
The Spring reference states that
The convention is to use the standard Java convention for instance field names when
naming beans. That is, bean names start with a lowercase letter, and are camel-cased from
then on. Examples of such names would be (without quotes) 'accountManager',
'accountService', 'userDao', 'loginController', and so forth.
It is not normal to use "/pqr" as a bean name but you can do it . I would prefer using more user friendly names to the beans than using a "path" .
Check here for the convention .

Spring bean with no id or name

I'm reviewing some Spring code, and I see a few bean defs that do not have an id or a name.
The person who did it is not around to ask.
The application is working fine.
I am not familiar what this necessarily means.
Anybody know if this means anything in particular?
Some beans are not required to be accessed by other beans in the context file or programmatically. So as mentioned by JacobM, they don't require an id or name as they're not referenced.
Such an example would be a PropertyPlaceholderConfigurer, which reads a property file, then allows for runtime property replacement in the context definition.
The example definition would be
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="myapp.properties" />
</bean>
The JavaDoc provides further documentation on this object, but further on in the file you can reference properties from your file by just using the standard template replace placeholder ${...}.
One possibility is that you can define a bean in place, and so you don't need an id since you don't need to refer to it from anywhere else. Say I have a Foo object that takes a Bar property:
<bean id="foo" class="Foo">
<property name="bar">
<bean class="Bar">
</property>
</bean>
The Bar bean doesn't need a name because it's only used to set that one property.
Check the possibility of auto-wiring. An other bean could reference the unnamed bean by having the autowire property set to byType.
This is just a guess. Without a concrete example, I can't say any more.
The id and name attributes are optional and are used to reference the bean definition from other definitions. Look at the official Spring documentation for more detail.
take a look at https://docs.spring.io/spring/docs/4.3.12.RELEASE/spring-framework-reference/htmlsingle/#beans-beanname it says,
You are not required to supply a name or id for a bean. If no name or id is supplied explicitly, the container generates a unique name for that bean. However, if you want to refer to that bean by name, through the use of the ref element or Service Locator style lookup, you must provide a name. Motivations for not supplying a name are related to using inner beans and autowiring collaborators.
Also, Beans such as BeanPostProcessor, BeanFactoryPostProcessor and PropertyPlaceholderConfigurer are automatically detected by application context and typically won't have name
If you consider any spring bean, Spring mandates it to have an identifier. In case, if you have not provided any identifier (via id or name attribute) to a bean in your configuration, you won't run into exceptions. Spring will manage such situation by assigning a default identifier. it has BeanNameGenerator to assign default name. <bean class="com.package.name.TestBean"> will be named as "com.package.name.TestBean" #Bean kind of beans will have its method name as bean name
thus, in your code, for some reason, you can skip naming few beans and the code still works if you are accessing those beans with their default name
credits : https://www.javacodegeeks.com/2013/02/spring-bean-names.html
Beans without id or name can still be referenced by the class name. Spring names those beans automatically using the class name and if there is more than one bean of the same class it appends a number to them.
Anonymous beans are usually defined inside a property tag, but if they're just there maybe there's autowiring configured in some other beans.
Anyway, I think adding a name or id to those beans won't break your application.
As a couple of people mentioned above, not all bean-grabbing is based on name/ID; some of it is based on type. For example, there is a method
BeanFactoryUtils.beansOfTypeIncludingAncestors(...)
that grabs all the beans of some given type. This is used for example by the Spring Web MVC DispatcherServlet (among many other places) to discover beans by type, such as HandlerMappings, HandlerAdapters, HandlerExceptionResolvers and so forth. Contrast this with cases where the bean must have a specific well-known name/ID to be found, such as the LocaleResolver (ID must be "localeResolver" or it won't be found) and ThemeResolver (ID must be "themeResolver" or it won't be found).
Beans defined without name and ID can be accessed with a generated ID (full package name and class name), for example:
bean defined as
<bean class="pl.finsys.initOrder.TestBeanImpl">
can be accessed by
TestBean bean = (TestBean) ctx.getBean("pl.finsys.initOrder.TestBeanImpl");
//Bean Cfg File without Bean id
<bean class="com.ds.DemoBean">
<property name="msg" value="Hello"/>
</bean>
//We can Access
Object obj=factory.getBean("com.ds.DemoBe
its not a mandatory to provide java Bean Id..If we are not providing Bean Id,our Container Provides the Default Been Id.Default Bean Id look like as
"(Package Name).(Bean Class Name)#N"where N=0,1,2,......etc.
It seems there is a subtle difference between unnamed and named bean behaviour. If you have an XML config file imported twice, each named bean will be created only once, but an unnamed bean will be created as many times as its definition is included. When trying to autowire such a bean by type, it leads to errors like this:
No qualifying bean of type [your.class.Name] is defined: expected single matching bean but found 4

Resources