Spring injecting one reference bean into another reference bean - spring

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"/>

Related

jee:remote-slsb use custom factory

i have this definition for calling an EJB
<util:properties id="ejbJndiConfig" location="file:/path/to/ejb-jndi-config.properties" />
<jee:remote-slsb id="myEjbService"
jndi-name="myEjbName"
business-interface="foo.bar.MyBusinessInterface"
cache-home="false"
lookup-home-on-startup="false"
refresh-home-on-connect-failure="true"
environment-ref="ejbJndiConfig"
expose-access-context="true">
</jee:remote-slsb>
All is working great and an instance of:
org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean is created to call the EJB method. But what about if i want to change this default behaviour and change the used class?
With old style spring we can do something like this:
<bean id="service" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="remoteInvocationFactory" ref="invocationFactory"/>
....
</bean>
<bean id="invocationFactory" class="src.rmi.CustomRemoteInvocationFactory"/>
is possible with new definition style?

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).

I still don't get how to avoid the use of getBean()

I'm new to Spring and I've read many guides on how to inject beans. Curiously, in every example I see, they use getBean in a class main method (not what I need). Also I've read many forums and questions related to how not to use getBean but I still can't figure out the best approach for my app.
I'm refactoring a web app that is highly coupled and without design patterns. Every business class has a corresponding DAO class, every DAO class extends a super DAO which handles the connection and other stuff. The problem here is that every DAO needs, in the constructor, some database config parameters that are being passed from the business class. What I'm trying to do is to put these parameters in a DBConfig bean and inject them into every DAO allowing me to create the DAO object from every business class simply, for example: dao = new myDAO().
How can I inject the DBConfig bean into every DAO "automatically"? Should I use getBean in the super DAO?
Your config could look like this:
<bean id="daoConfig1" class="com.foo.dao.DAOConfig">
<property name="dbUrl" value="jdbc://urlForDao1" />
...
</bean>
<bean id="dao1" class="com.foo.dao.DAO1">
<constructor-arg ref="daoConfig1" />
</bean>
<bean id="business1" class="com.foo.service.Business1">
<property name="dao" ref="dao1" />
</bean>
<bean id="daoConfig2" class="com.foo.dao.DAOConfig">
<property name="dbUrl" value="jdbc://urlForDao2" />
...
</bean>
<bean id="dao2" class="com.foo.dao.DAO2">
<constructor-arg ref="daoConfig2" />
</bean>
<bean id="business2" class="com.foo.service.Business2">
<property name="dao" ref="dao2" />
</bean>
Or share a single daoConfig instance between all daoX beans, if that's what you want.
You can then use the folowing to handle the business logic:
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"beans.xml"});
Business1 b1 = (Business1) context.getBean("business1");
b1.doStuff();
Or better still, use something like Spring MVC that can wire the business beans into your controllers without needing to call getBean().

Java Spring anonymous bean without parent

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.

Resources