Java Spring anonymous bean without parent - spring

I try to understand code:
<bean id="topBean" class="com.topBean" >
<property name="helpbean" ref="helpBean" />
<property name="topFolder">
<bean parent="someparent">
<property name="propertyName" value="value1"/>
</bean>
</property>
</bean>
I try to find parent bean with name "someparent" but without success.
Is it allowed?

There has to be a bean called someParent somewhere in the context, or in a parent context. It's not valid otherwise.
Remember, contexts can themselves have parent contexts. Beans in a child context can refer to bean in their parent contexts.

Related

Spring injecting one reference bean into another reference bean

In the below spring configuration snippet, injecting reference of "SomeManager" into bean "SomeWorker" and "SomeLocal". The reference of "SomeLocal" is also injected into "SomeWorker".
My doubt is is it possible to inject the same reference of "SomeManager" injected into "SomeWorker" into another bean, like here in "SomeLocal".
Problem is if i inject it separately into "SomeWorker" and "SomeLocal" than unnecessarily there will be two instances of "SomeManager" which is basically not required in this scenario as "SomeLocal" is referred only within the "SomeWorker"
<bean id="SomeWorker" class="com.test.worker.SomeWorker">
<property name="someManager" ref="SomeManager" />
<property name="someLocal" ref="SomeLocal"/>
<bean id="SomeLocal" class="com.test.local.SomeLocal">
<property name="someManager" ref="SomeManager" />
</bean>
<bean id="SomeManager" class="com.test.manager.SomeManager"/>

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.

How to guarante Spring PropertyPlaceHolder been loaded before specified bean been generated?

I am working with Spring 3.2 and I am trying to define some beans with property place holders.
<context:property-placeholder location="classpath*:/config/db2.properties"/>
<bean id="testBean" class="com.mywork.func.service.TestBean">
<property name="driverClassName" value="${jdbc.driver}" />
...
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
...
</bean>
In the db.properties, I have
jdbc.driver=oracle.jdbc.driver.OracleDriver
As the two beans listed in the snippet are both defined with placeholders like "${jdbc.driver}", but I got different things for the properties in beans:
for the testBean I got "oracle.jdbc.driver.OracleDriver" while in dataSource I got "${jdbc.driver}".
Some testing show that the "datasource" was init before the property-placeholder been initializated property while "testBean" was init after that.
Could anyone give me some clues how to ensure the property placeholder been initialized as early to to ensure any other beans I expected to utilize the property place holders can got proper values?
There was a question almost the same as mine, but with no effective answer to it.
How to guarantee Spring bean order? PropertyPlaceHolder issue

injecting a spring bean property different values according to its context

I have a spring bean my_bean with a property my_map, and I want to inject it with the value "X" or with the value "Y". The bean:
<bean id="my_bean">
<property name="my_map">
<map>
<entry key="p" value="X" />
</map>
</property>
</bean>
It's referenced in a very deep hierarchy by the bean root_a:
<bean id="root_a">
<ref bean="root_a_a"/>
</bean>
<bean id="root_a_a">
<ref bean="root_a_a_a"/>
</bean>
<bean id="root_a_a_a">
<ref bean="my_bean"/>
</bean>
and this entire deep hierarchy is referenced again from the bean root_b. In the ref of my_bean from this hierarchy I would the property to be injected with the value "Y", but I would not like to duplicate the entire hierarchy twice.
<bean id="root_b">
<ref bean="root_a_a"/>
</bean>
How do I do this in the spring XML? can you think of a clever spring EL solution? something else? I prefer all my configuration to be done in the XML and no Java code...
By default Spring beans are singletons, which means that once bean="my_bean" is created it is shared between other components e.g. shared between A => bean id="root_a_a_a" and B => bean id="root_b_b_b"
The answer to your question depends on what exactly you are trying to achieve.
Two Beans
If bean="my_bean" does not need to be shared between A and B, then create two beans:
inject this one to A
<bean id="myBeanX" class="My">
<property name="culprit" value="X"/>
</bean>
and this one to B
<bean id="myBeanY" class="My">
<property name="culprit" value="Y"/>
</bean>
notice they both are instances of the same class.
You can also inline them into collaborators (A / B) if you don't need them for anything else:
<bean id="root_a_a_a">
<constructor-arg>
<bean class="My">
<property name="culprit" value="X"/>
</bean>
</constructor-arg>
</bean>
You can also have a factory bean that creates root_a_a_a given the property for a class My, but that would be an overkill.
Single Bean
In case A and B needs to share the exact same reference to bean="my_bean", the question is: are you ok with A and B changing my_bean's state after my_bean is created? Probably not.
If you are, which would be 0.41172% chance, you can change my_bean's value to whatever you need in A's or B's constructors => would not recommend
Hence you either would go with the Two Bean approach (which is most likely what you want), or you would need to refactor a property for "X" and "Y" into another e.g. myConfig component.
EDIT after the question was edited
If root_a and root_b will not be used together in the same instance of the context,you can use Spring Profiles (example), or SpEL / Property Based solutions (example)
e.g.
<bean id="my_bean">
<property name="my_map">
<map>
<entry key="p" value="${ENV_SYSTEM:X}" />
</map>
</property>
</bean>
It will set it to X by default, unless a ENV_SYSTEM system variable is set (e.g. to Y).

MethodInvokingBean question

I have a method invoking bean which calls a method to perform some sort of initialization on a targetBean and another bean who needs a twitter class albeit initialized.
<bean id="twitter" class="twitter4j.Twitter"></bean>
<bean id="twitterInjector"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="twitter"/>
<property name="targetMethod">
<value>setOAuthConsumer</value>
</property>
<property name="arguments">
<list>
<value>consumerKey</value>
<value>consumerSecret</value>
</list>
</property>
</bean>
<bean id="MyPageController"
class="com.hardwire.controller.MyPageController">
<property name="twitter" ref="What should I put here? twitter or
twitterInjector?/>
.
.
.
</bean>
What should I inject into the MyPageController, twitterInjector or twitter?
MethodInvokingFactoryBean - like all other factory beans in Spring - is primarily intended to produce a new bean; in this particular case by invoking a method of some other bean (or class). Your setOAuthConsumer method doesn't seem like it would return a bean, so using MethodInvokingFactoryBean may not be the best approach in these circumstances.
If I am mistaken and it does return a bean (in which case consider renaming it) and that's the bean you want injected in your controller then you should use twitterInjector as ref value. If you really want twitter in your controller, then you should use twitter.

Resources