how to control the sequence of object creation in spring? - spring

in xml based approach, we configure the bean definition in xml ,
beans will be created in the order we have defined the beans.
1) <beans>
<bean id="a" class="com.abc.a"/>
`<bean id="b" class="com.abc.b"/>`
</beans>
Here , a will be created first before b.
2)<beans>
<bean id="a" class="com.abc.a">
<property name="c" ref="c"/>
</bean>
<bean id="b" class="com.abc.b/">
<bean id="c" class="com.abc.c/">
here c will be created first, then a then b.
In case of annotation driven approach, how to control the sequence of object creation? using ordered interface ?

Spring container creates the dependent objects (because they are needed by the main objects as per the object graph) first both in xml & annotation approach.
In case of annotation driven approach, how to control the sequence of object creation? using ordered interface ?
You can't control the order of objects as the dependent objects are always needed to be created first and then followed by the main objects.
The order interface is for a different purpose which is to push the objects into a list using autowired.
You can refer the example in the below link for using #Order to set/push an object into a list:
What is the use of #Order annotation in Spring?

Spring has an Order attribute of java config and an order attribute for xml configuration to control the order in which beans are created. (Lower values means earlyer creation, negative number are allowed too)
An other way is to control the order is DependsOn annotation/attribute.

Related

How to get set elements in the same sequence as in a Spring bean definition

I have a lot of bean definitions that look similar to this
<bean id="TransformationMapOrganization " class="com.artifact_software.adt.plugin.transformation.RemoveColumnsTransformationImpl">
<property name="pluginId" value="Remove Division, Department, and Cost Code" />
<property name="dataStoreName" value="person_data"/>
<property name="columnNames">
<set>
<value>Division</value>
<value>Dept Code</value>
<value>Cost Code</value>
</set>
</property>
</bean>
In the code, the columnNames are defined as:
protected List<String> columnNames;
It appears that erroneous duplicate values are ignored rather causing an error which is good. I hope that I can count on that since it does make life easier!
What set implementation will Spring use?
What is the correct way to iterate through columnNames to get the columnNames in the same sequence as they are specified in the bean?
You can set the implementation class via <set set-class="com.my.SetImpl" />, (see current doc). (com.my.SetImpl must implement java.util.Set)
alternatively: define targetClass on your SetFactoryBean...
If omit, current spring, will use java.util.LinkedHashSet.
More correct, reliable & future-safe it would be to map columnNames as java.util.Set not as a List (+ to use set-class).
If no set-class attribute is supplied, the container chooses a Set implementation.
(in your case,) Obviously spring manages to convert from set to list "smoothly" ("by hand" it's also easy done thx to api design). Spring (seems to) also preserves you distinct entries, LinkedHashSet implementation additionally guarantees/should "preserve order"...
Your Bean definition and field names are different. Change
<property name="ColumnNames">
to
<property name="columnNames">

Spring Bean entry with Same Alias - one Child another Parent class

I have a requirement to Override a default service class with same Alias in SPRING bean.So that new service class is called with same Alias . I added the below code in Spring xml, here "CustomDefaultService extends DefaultService"
1) Does Spring give precedence to the child class in creating instance and referring via same alias name ?
2) Or its random for Spring if we have Child or parent to assign to same alias name?
<alias alias="modelService" name="customMefaultService" />
<bean id="customMefaultService" class="com.tisl.CustomDefaultService" parent="defaultModelService">
</bean>
Which bean is actually used depends on the context loading order.
Spring will use the last bean created. So if you can ensure that the customMefaultService is created after the DefaultService.
To ensure the order you could use the depends-on. E.g:
<alias alias="modelService" name="customMefaultService" />
<bean id="customMefaultService" class="com.tisl.CustomDefaultService" parent="defaultModelService" depends-on="defaultModelService">
</bean>
As you are already using parent I would assume that the order is already correct anyway.
Also make sure that setAllowBeanDefinitionOverriding is set to true (should be as true is the default)

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.

When to use <ref bean> and when to use <ref local> in Spring?

When to use <ref bean="service" /> and when to use <ref local="service" /> in Spring?
Specifying the target bean by using the bean attribute of the ref tag is the most general form, and will allow creating a reference to any bean in the same BeanFactory/ApplicationContext (whether or not in the same XML file), or parent BeanFactory/ApplicationContext. The value of the bean attribute may be the same as either the id attribute of the target bean, or one of the values in the name attribute of the target bean.
<ref bean="someBean"/>
Specifying the target bean by using the local attribute leverages the ability of the XML parser to validate XML id references within the same file. The value of the local attribute must be the same as the id attribute of the target bean. The XML parser will issue an error if no matching element is found in the same file. As such, using the local variant is the best choice (in order to know about errors are early as possible) if the target bean is in the same XML file.
<ref local="someBean"/>
This is from the Spring source reference here
The local attribute on the ref element is no longer supported in the 4.0 beans xsd since it does not provide value over a regular bean reference anymore. Simply change your existing ref local references to ref bean when upgrading to the 4.0 schema.
<ref local="someBeanId"> should be used when you have a duplicate id in your parent-child config files and you want to distinguish between the two in either config file.
<ref parent="someBeanId"> should be used in the child config file to reference the parent id.
<ref bean="someBeanId"> should be used when you do not have a duplicate id in your parent-child config files.
<ref local=".."> requires that the bean being referenced is in the same config file.
<ref bean="..."> requires only it to be in the same context, or in a parent context.
The difference is primarily one of documentation. If you see <ref local="...">, then you know you need only look in the same file to find it. Other than that, there's not much difference. I would generally use <ref bean="..."> in most cases.
In spring 4.1
the local attribute is not valid.
i used in the parent xml a name attribute for the
and in the child file a referenced the bean by the alias i gave already.

Dynamically configuring java beans based on property file in Spring

Wondering if there is a way to dynamically instantiate beans based on set of values in your property file using PropertyPlaceholderConfigurer class.
I have a java bean say Student with two attributes: "name" and "subject"
I have a property file with:
student.1.name=student1name
student.1.subject=student1subject
student.2.name=student2name
student.2.name=student2subject
Now I have a Classroom object that can take a list of students.
I am wondering if there is a way we could do this using Spring. The challenge here is that the number of students could vary.
If there was only one student object then:
<bean id="student" class="com.abc.Student">
<property name="name" value="${student.1.name}" />
<property name="subject"
value="${student.1.subject}" />
</bean>
<bean id="classRoom" class="com.abc.ClassRoom">
<property name="student" ref="student" />
</bean>
would have worked. But in this case we have a list of n Students. And the value of n could vary depending on the number of entries in the properties file.
I'm with Kevin--IMO you're going about this the wrong way.
One possible workaround would be to create a bean that takes the property file as an argument, reads it in, and exposes a list of students (which would need to be indexed on something, like the n in the existing property file).
The classroom bean could then use that list of students.
But it sure looks like you're trying to duplicate the functionality of a DB, without a DB, in an awkward way.
I don't think there's a way to do that with PropertyPlaceholderConfigurer. Usually when I have a situation like that I choose a configuration format of either JSON or XML and use GSON/Jackson/JAXB to unmarshall the data into objects.

Resources