How to refer to current bean in spring expression language - spring

I am using spring-3.2.2. I am new to spring and using the Spring Expression Language for the first time. Please consider the below snippet of spring configuration file in which I am facing the issue.
<bean id="bean3" class="com.springaction.testcollection.PersonBean">
<property name="name" value="Prakash" />
<property name="age" value="62" />
<property name="salary" value="30000" />
<property name="bonus" value="#{salary*T(PersonBean).count}" />
</bean>
In the above snippet, I want to use the salary field of the same bean(bean3) to calculate the bonus value. I just want to know how to refer the current bean's fields in the spring-configuration file? Is it possible? If not are there any alternatives to resolve the issue ?

Related

How Spring manages map-merge='true' in case of same key in parent map?

I have following 2 configs :
config-1.xml
---- import config-2.xml -----
<bean id="map1" class="java.util.HashMap" parent="map2">
<constructor-arg>
<map merge="true">
<entry key="key1" value="value1"/>
<entry key="key2" value="value2"/>
</map>
</constructor-arg>
</bean>
config-2.xml
<bean id="map2" class="java.util.HashMap">
<constructor-arg>
<map>
<entry key="key1" value="new_value1"/>
<entry key="key3" value="value3"/>
</map>
</constructor-arg>
</bean>
How spring manages this merge ?
I will load bean through config-1.xml ( It has config-2.xml as import).
So what I want is key1=new_value1
Please note that I cant touch config-1.xml as its used by other code so I should load new value via config-2.xml which is specific to my code.
Wherever I refer map1 , it should have following for my code :
key1=new_value1
key2=value2
key3=value3
Looking at the Spring docs for Bean Definition Inheritance, it seems to me to pretty clearly say that anything specified in both child and parent will cause the child definition to override the parent definition:
https://docs.spring.io/spring-framework/docs/3.0.0.M4/reference/html/ch03s07.html
Maybe it could be a little more clear, but what the docs say seems to confirm what you're saying and what the testing you've cone confirms. Take this example:
<bean id="inheritedTestBean" abstract="true"
class="org.springframework.beans.TestBean">
<property name="name" value="parent"/>
<property name="age" value="1"/>
</bean>
<bean id="inheritsWithDifferentClass"
class="org.springframework.beans.DerivedTestBean"
parent="inheritedTestBean" init-method="initialize">
<property name="name" value="override"/>
<!-- the age property value of 1 will be inherited from parent -->
</bean>
The fact that nothing is said about what value the name property will take, but its value for the example is chosen as override, seems to pretty clearly suggest that override will be the resulting value of the child's name property. Further, the fact that it is mentioned explicitly that the age property will be inherited from the parent strongly suggests that the name property will not be, meaning that it will instead be overridden by the child definition. This seems like nothing but obvious behavior to me.

How to define a PropertyPlaceholderConfigurer local to a specific bean?

I've been using org.springframework.beans.factory.config.PropertyPlaceholderConfigurer and in my experience ("citation needed" LOL) it sets the property values globally.
Is there a way to specify different PropertyPlaceholderConfigurer instances for different beans within the same application context xml?
My current code is similar to
<bean id="a" class="X">
<property name="foo" value="bar"/>
<property name="many" value="more"/>
</bean>
<bean id="b" class="X">
<property name="foo" value="baz"/>
<property name="number_of_properties" value="a zillion"/>
</bean>
I would like to do something like (pseudo-code below):
<bean id="a" class="X">
... parse the contents of "a.properties" here ...
</bean>
<bean id="b" class="X">
... parse the contents of "b.properties" here ...
</bean>
The above is non-working pseudo code to illustrate the concept; the point being, I want a different properties file to feed each bean.
WHY?
I want to have those specific properties in separate properties file and not in XML.
I think the following link can br helpful to you.
Reference Link
where #Value("${my.property.name}") annotation is used to bind the property file to a variable of type Properties which will reside in your bean class where you intend to use that properties file.
and you can define multiplte proprtiesplaceholder as below:
<bean id="myProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath*:my.properties</value>
</list>
</property>
</bean>
and use the id as reference in your bean variable to initialize properties file to the bean.
And it will be handy to include with placeholder bean.
Kindly refer Importance of Unresolvable Placeholder link for detailed info regarding its usage.
Hope this was helpful.

Difference b/w primary and autowire-candidate attribute of bean tag in spring

I am new to spring. When i am going through auto wiring byType i came to know about these attributes primary and autowire-candidate.
I didn't get the exact difference b/w these two as setting these parameter to false will make the other bean a candidate for autowiring.
Can anybody help me in understanding these two.
Thanks
Let say there is interface
interface Translator { String translate(String word);}
Your application use the translator widely to translate from English to Polish. However, is some specific case you want to use dedicated translator, because vocabulary is specific. For example, string always means "sequence of characters" but never "underwear".
Sample configuration:
<bean class="EnglishToPolishTranslator" />
<bean class="ComputerScienceEnglishToPolishTranslator" autowire-candidate="false"/>
Everywhere EnglishToPolishTranslator will be autowired except some concrete place where ComputerScienceEnglishToPolishTranslator will be injected by reference.
Some day next customer arrive with requirement: use simpler words. The requirement is achieved by class SimpleEnglishToPolishTranslator. But computer science translator should remain unchanged: it is too costly to modify it.
Your company want keep product easy to maintain. Base application will not be modified, but for the customer the product will extended with extra library configured:
<bean class="SimpleEnglishToPolishTranslator" primary="true"/>
In result, everywhere SimpleEnglishToPolishTranslator will be used except computer science area.
Maybe it is overcomplicated, but shows a difference I found between autowire-candidate and primary
BTW, "autowire-candidate" doesn't have corresponding annotation. It looks to me that "autowire-candidate" is dead end in Spring evolution
if we configure bean for more than one time with different ids then IOC will throw an Exception. To overcome this duplicate beans problem, we can use autowire-candidate=”false” or primanry="true"
Example: i have two classes Mobile and Processor
Case -1: autowire-candidate=”false”
<bean id="mobile" class="com.Mobile" autowire="byType">
<property name="mobileName" value="Redmi"></property>
<property name="mobileModel" value="Note 5"></property>
</bean>
<bean id="process1" class="com.Processor"
autowire-candidate="false">
<property name="process" value="2GHz"></property>
<property name="ram" value="4GB"></property>
</bean>
<bean id="process2" class="com.Processor">
<property name="process" value="1GHz"></property>
<property name="ram" value="3GB"></property>
</bean>
As per above configuration, process1 bean will be ignored and process2 bean will be injected.
Case -2: primanry="true"
<bean id="mobile" class="com.Mobile" autowire="byType">
<property name="mobileName" value="Redmi"></property>
<property name="mobileModel" value="Note 5"></property>
</bean>
<bean id="process1" class="com.Processor" primary="true">
<property name="process" value="2GHz"></property>
<property name="ram" value="4GB"></property>
</bean>
<bean id="process2" class="com.Processor">
<property name="process" value="1GHz"></property>
<property name="ram" value="3GB"></property>
</bean>
As per above configuration, process2 bean will be ignored and process1 bean will be injected.

Spring MVC: Set property value based on input

I have a login page where I have to select which database it should connect
I have my configuration like this:
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver" />
<property name="url" value="jdbc:db2://my_server:10000/DATABASE_1" />
<property name="username" value="galadm" />
<property name="password" value="galadm" />
</bean>
I using Spring JDBC Template
Can I write something like this
<property name="url" value="jdbc:db2://my_server:50000/DATABASE{database_which_I_get_from_input}" />
I don't mind to have initial value i.e. DATABASE_1
Seems that the AbstractRoutingDataSource is a viable solution for you. Its the layer that acts as an intermediary between the multiple datasource, and determines which one to use dynamically.
The following blog solution describes how you can switch based on some attribute of the user’s context
https://spring.io/blog/2007/01/23/dynamic-datasource-routing/

In spring xml config,how to automatically get the current bean's ID value?

I use quartz in spring xml, I have many config like above config~~
I want to known ,automatically get the id value of the current bean
Not every time I hand-written the value of the current bean!!
<bean id="openBaiduTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<bean p:targetObject-ref="baiduManager" p:targetMethod="createOpenBaiDu" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" />
</property>
<property name="cronExpression" value="#{p_schedule['openBaiduTrigger.cronExpression']}" />
</bean>

Resources