spring bean: good XML data structure for many classes? - java

I am working on a demo with Java Spring Bean. I have a structure in the applicationContext.xml. Something like that:
<bean id="Transfer1" class="bank.Transfer">
<property name="id" value="1" />
<property name="firstname" value="Thomas" />
<property name="lastname" value="Bäcker" />
<property name="transferdate" value="2016-11-15" />
<property name="amount" value="300" />
</bean>
<bean id="Transfer2" class="bank.Transfer">
<property name="id" value="2" />
<property name="firstname" value="Bob" />
<property name="lastname" value="Sapp" />
<property name="transferdate" value="2016-12-01" />
<property name="amount" value="2700" />
</bean>
//
// followed by Transfer3, Transfer4...
//
I am wondering if there is a better solution, data structure for this. May be something where i can put all Transfers in one Bean instead a long list of Beans. Thx for any advice!

Actually you do not have many classes. You have many instances of the same class...
There is nothing bad with what you done, just because you need 8 instances of the same class with different values only for demo.
If you'd like to combine them into one "holder" bean as collection (array, list, set, map...) you can create your own class (i.e. bank.AllTransfers) with property as any collections (array, list,set,map) and define another bean like
<bean id="allTransfers" class="bank.AllTransfers">
<property name="transfersCollection">
<list>
<ref bean="Transfer1"/>
<ref bean="Transfer2"/>
</list>
</property>
</bean>
Also take a look at Spring Util package (namespace is http://www.springframework.org/schema/util). there are bunch of elements to do the same without another wrapper bean like:
<util:list name="transfersList" list-class="java.util.ArrayList" value-type="bank.Transfer">
<ref bean="Transfer1">
<ref bean="Transfer2">
</util:list>
In that case you will have just a bean of class java.util.ArrayList you can reference to from another beans i.e.
<bean id="allTransfers" class="bank.AllTransfers">
<property name="transfersCollection">
<ref bean="transfersList"/>
</property>
</bean>
for those examples you have to keep your 8 beans definitions "as is".
Of course you can put them right in your list like:
<bean id="allTransfers" class="bank.AllTransfers">
<property name="transfersCollection">
<list>
<bean id="Transfer1" class="bank.Transfer">
<property name="id" value="1" />
<property name="firstname" value="Thomas" />
...
</bean>
<bean id="Transfer2" class="bank.Transfer">
<property name="id" value="2" />
<property name="firstname" value="Bob" />
...
</bean>
</list>
</property>
</bean>
there are many-many possibilities...
PS. but if you still want to keep your 8 beans construction in the Spring context (not from DB, external .properties file ...) you have to have them defined anyway.

Related

Init Custom inner object using spring bean xml

I have this kind of class:
Class Food
int type
String name
Class Dog
String dogName
Food food
I want to Init the Dog class using Spring properties, I have no problem to init the dogName value by doing this:
<bean id="dog" class="....Dog">
<property name="dogName" value="dog"/>
...
</bean>
How to set a value for the Food Object?
Use the ref in to refer to the bean id of the food.
<bean id="food" class="....Food"></bean>
<bean id="dog" class="....Dog">
<property name="dogName" value="dog"/>
<property name="food" ref="food"/>
</bean>
<bean id="dog" class="c...dog">
<property name="dogName" value="dog"/>
<property name="food" >
<bean class="...food">
<property name="type" value="1"/>
<property name="name" value="chicken"/>
</bean>
</property>
</bean>
and in case of inner but you can't use it outside of the parent bean tag
<bean id="dog" class="c...dog">
<property name="dogName" value="dog"/>
<property name="food" >
<bean class="...food">
<property name="type" value="1"/>
<property name="name" value="chicken"/>
</bean>
</property>
</bean>
<property name="food">
<bean class="...Food">
<property name="type" value="1"/>
<property name="name" value="Apple"/>
</bean>
</property>
See Spring 3.3.2.3. Inner beans:
A element inside the or elements is used to define a so-called inner bean. An inner bean definition does not need to have any id or name defined, and it is best not to even specify any id or name value because the id or name value simply will be ignored by the container.
<bean id="outer" class="...">
<!-- instead of using a reference to a target bean, simply define the target bean inline -->
<property name="target">
<bean class="com.example.Person"> <!-- this is the inner bean -->
<property name="name" value="Fiona Apple"/>
<property name="age" value="25"/>
</bean>
</property>
</bean>
Use the ref in <property> to refer to the bean id of the food.
<bean id="food" class="....Food">
</bean>
<bean id="dog" class="....Dog">
<property name="dogName" value="dog"/>
<property name="food" ref="food"/>
</bean>

Spring+Hibernate+java :Connecting to multiple database after running application

If application is running and connected to Database-1. Through application I want to copy certain data from one Database (it can be Database-1 on any other) to another database. There can be 3-4 database. And schema is exactly same for all the database. Is it possible to do so?
I have read about "AbstractRoutingDataSource" here. But I don't wan't to connect to database during runtime. It should be after runtime.
my spring-config.xml contains bean for JdbcTemplate
<bean id="EnvJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="envDataSource" />
</property>
</bean>
I have created bean for envDataSource (database 1)
<bean id="envDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"/>
<property name="url"/>
<property name="username"/>
<property name="password"/>
</bean>
Seems like you just need to create more beans, and inject them where needed, and call them when you need. This isn't that smart, but you don't need over engineer this.
<bean id="envDataSource1" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"/>
<property name="url"/>
<property name="username"/>
<property name="password"/>
</bean>
<bean id="envDataSource2" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"/>
<property name="url"/>
<property name="username"/>
<property name="password"/>
</bean>
<bean id="EnvJdbcTemplate1" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="envDataSource1" />
</property>
</bean>
<bean id="EnvJdbcTemplate2" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="envDataSource2" />
</property>
</bean>
There is a built in feature in Hibernate to support multiple schemas/databases. find it here

Query Timeout spring xml Parameter

I got this bean in my data-access-functions-config.xml:
<bean id="pbfuLinkTrasmissionDao" class="******.zja.dao.stored.StoredDao">
<property name="dataSource" ref="easyDataSource" />
<property name="parameterHandlerManager" ref="parameterHandlerManager" />
<property name="queryTimeout" value="${store.procedure.timeout}" />
<property name="storedDaoConfiguration">
<bean class="******.zja.dao.stored.config.StoredDaoConfiguration">
<property name="spSchema" value="DSVIL" />
<property name="spPackage" value="WAPK_EASY_SERVICE" />
<property name="spName" value="wapr_PolicyCustomerLinkage " />
<property name="storedType" value="PROCEDURE" />
<property name="spParameters">
<list>
My .property file got:
store.procedure.timeout=1
I have problems with this property
<property name="queryTimeout" value="${store.procedure.timeout}" />
The procedure runs for about 5 seconds, but it does not give any timeout.
Am I missing something for this configuration?
The procedure runs well, also the call. I have only to add this queryTimeout. Is right to use this in this way? Do I have to add some others parameters or java parameters?
it does not go in timeout even if i do this:
<property name="queryTimeout" value="1" />

Issue in NOT being able to supply HashMap as "value" for a given key in applicationContext.xml

I want to use a Hashmap as a value for a key in my applicationContext.xml file.
That is, both the keys and the values for the key that we specify (as given below) would be supplied at runtime ,in the xml file.
<beans>
<bean id="movieDetails" class="org.gis.gvb.MovieDetails">
<property name="name" value="Sri Raghavendra Mahatyam"/>
<property name="censorRating" value="U"/>
<property name="userRating" value="*****"/>
<property name="language" value="Telugu"/>
<property name="twoD3DND" value="2D"/>
<property name="releaseYear" value="1986"/>
<property name="genre" value="Devotional"/>
<property name="castNCrew" value="Director=Trivikram Srinivas,Producer=Suresh
Productions,Music=Devisri Prasad,Hero=Venkatesh,Heroine=Katrina Kaif"/>
</bean>
</beans>
Please help me achieve this.
When tried,I am getting error saying cannot convert from String to HashMap.
Thanks a lot,
Bhaskar Gundu.
You have achieve like this
<bean id="movieDetails" class="org.gis.gvb.MovieDetails">
<property name="youMapName">
<map>
<entry key="name" value="Sri Raghavendra Mahatyam"/>
<entry key=="censorRating" value="U"/>
</map>
</property>
</bean>
Define a Map like this first inside your applicationContext.xml:
<util:map id="myMap" value-type="java.lang.String">
<entry key="entry1" value="value1" />
<entry key="entry2" value="value2" />
...
</util:map>
Then use this Map in any bean of yours like this:
<bean id="myBean" class="com.sample.beans">
<property name="myMap" ref="myMap" />
</bean>

Upgrading to springframework.scheduling.concurrent?

As of Spring 3.0 the ScheduledTimerTask is deprecated and I can't understand how to upgrade to org.springframework.scheduling.concurrent.
<bean id="timerFactoryBean" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref bean="onlineTimeSchedule" />
</list>
</property>
</bean>
<bean id="onlineTimeSchedule" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="timerTask" class="com.example.OnlineTimerTask" />
</property>
<property name="period" value="60000" />
<property name="delay" value="1000" />
</bean>
Where the OnlineTimerTask extends java.util.TimerTask. It's simple task which publishes a message to publisher every minute. I checked the documentation, but nothing.. I can't understand which way to use from the concurrent package and which suits the best.
Also I want to turn this xml into #Bean in Java.
EDIT: So I tried to implement the xml with #Bean and #Configuration instead and here is what I got.
#Configuration
public class ContextConfiguration {
#Bean
public ScheduledExecutorFactoryBean scheduledExecutorFactoryBean() {
ScheduledExecutorFactoryBean scheduledFactoryBean = new ScheduledExecutorFactoryBean();
scheduledFactoryBean.setScheduledExecutorTasks(new ScheduledExecutorTask[] {onlineTimeSchedule()});
return scheduledFactoryBean;
}
#Bean
public ScheduledExecutorTask onlineTimeSchedule() {
ScheduledExecutorTask scheduledTask = new ScheduledExecutorTask();
scheduledTask.setDelay(1000);
scheduledTask.setPeriod(60000);
scheduledTask.setRunnable(new OnlineTimerTask());
return scheduledTask;
}
}
Will the code above be correct replacement for xml? Will in my case the setScheduledExecutorTasks work properly? I mean will the referencing to the same bean instance, if onlineTimeSchedule() is called more than once, will work here?
scheduledFactoryBean.setScheduledExecutorTasks(new ScheduledExecutorTask[] {onlineTimeSchedule()});
Use org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean in place of org.springframework.scheduling.timer.TimerFactoryBean and use org.springframework.scheduling.concurrent.ScheduledExecutorTask in place of org.springframework.scheduling.timer.ScheduledTimerTask. You will need to adjust the property names and values as needed but, that should be pretty self evident.
Optionally, you could refactor your com.example.OnlineTimerTask to not extend java.util.TimeTask as the ScheduledTimerTask only requires a runnable.
Spring 4 configuration - Below configuration working after spring migration from 3.2.x to 4.6.x
<bean id="schedulerTask"
class="org.springframework.scheduling.support.MethodInvokingRunnable">
<property name="targetObject" ref="springJmsListnerContainer" />
<property name="targetMethod" value="execute" />
</bean>
<bean id="timerTask" class="org.springframework.scheduling.concurrent.ScheduledExecutorTask">
<property name="runnable" ref="schedulerTask" />
<property name="delay" value="100" />
<property name="period" value="60000" />
</bean>
<bean class="org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean">
<property name="scheduledExecutorTasks">
<list>
<ref bean="timerTask" />
</list>
</property>
</bean>
The answer is - add one "runnable" field
<bean id="scheduledExecutorTask"
class="org.springframework.scheduling.concurrent.ScheduledExecutorTask">
<!-- wait 10 milli seconds before starting repeated execution -->
<property name="delay">
<value>10</value>
</property>
<!-- run every 1 second -->
<property name="period">
<value>1000</value>
</property>
<property name="runnable">
<ref bean="checkInvokingTask"/>
</property>
</bean>

Categories

Resources