I have a system where I have an enum of Shops for example. These shows each have their own ShopCommand property (some of which share the same type of command class). from a method in the command class I then want to call send on a Spring Integration gateway. Where I'm confused is how to actually insantiate this gateway in spring. Ideally what I want is to construct the enum via XML configuration with command property being created also in spring, which has the property outGateway set via Spring. I'm not sure if I've made myself very clear with this descrition, if clarification is needed then just ask!
I think this is what you are asking for:
Say I have an enum for ShopType
public enum ShopType {
GROCERY, DEPARTMENT, MALL;
}
Then I have some Store bean that I want to setup via spring configuration. You can instantiate and use the enum like this:
<bean id="DEPTARTMENT_STORE" class="my.package.ShopType" factory-method="valueOf">
<constructor-arg value="DEPARTMENT"/>
</bean>
<bean id="searsStore" class="my.package.Store">
<property name="shopType" ref="DEPTARTMENT_STORE"/>
</bean>
The factory-method points to a static method that is used to create the object. So you can use the enum's method "valueOf" as a factory method.
Related
I am working on an application where I have two classes both implementing a common interface. So in time of bean declaration, I am going to mark one of them primary in my app-context.xml file. I can achieve this by simply declaring the primary bean like this:
<bean id="oracleImpl" class="com.me.dao.OracleImpl" primary="true">
</bean>
Now I don't want to hard code which of the beans is going to be the primary bean, rather want to read the true/false value from a properties file. So I went like this:
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="oracleImpl" class="com.me.dao.OracleImpl" primary="${oracle.primary}">
</bean>
<bean id="pgsqlImpl" class="com.me.dao.PgsqlImpl" primary="${pgsql.primary}">
</bean>
The values of oracle.primary and pgsql.primary are defined in the file jdbc.properties along with other jdbc (non-boolean) properties.
But it doesn't work and says, "'${oracle.primary}' is not a valid value for 'boolean'"
I have a feeling it is something to do with the xsd validators. Browsing through this site and google gave me this much idea, but got no real solution. Can any body help?
This will not work.
As of 3.2.5.RELEASE only the following bean definition elemets support property placeholder:
parent name
bean class name
factory bean name
factory method name
scope
property values
indexed constructor arguments
generic constructor arguments
See the BeanDefinitionVisitor's visitBeanDefinition method for the details. This method is used by the PlaceholderConfigurerSupport.
I would recommend you to create a feature request in the spring issue management system.
PS: if you create an issue please add a comment to the issues url.
I am developing a project and using 3rd party libraries. Let's say I use a library which gives me the object ExtObj. In my project I have a class MyObj, which uses ExtObj. How can I configure spring 3 to inject ExtObj in MyObj?
I tried to research the topic on the internet, but I didn't find a straight answer. I would like to use xml configuration and maybe (?) #Autowired, not #EJB or #Inject
Thanks in advance!
UPDATE
my guess was:
<bean id="myObj" value="me.MyObj">
<property name="extObj" value=" ... ??? ...">
</bean>
So, I don't know what I should put into value. I guess that's where the reference to the external object goes. But spring can only reference objects that have been already defined/configured in spring. So:
<bean id="extObj" value="ext.lib.ExtObj">
<bean id="myObj" value="me.MyObj">
<property name="extObj" value="extObj">
</bean>
Is that configuration right?
First you need to define a bean for your ExtObj in your application context (an xml file or a #Configuration class). Eg. if ExtObj has a constructor taking a String you can define the bean this way:
<bean id="extObj" class="ext.lib.ExtObj">
<constructor-arg value="SomeString"/>
</bean>
To define MyObj you can use constructor injection:
<bean id="myObj" class="me.MyObj">
<constructor-arg ref="extObj"/>
</bean>
or setter injection:
<bean name="myObj" class="me.MyObj">
<property name="extObj" ref="extObj"/>
</beans>
If you use setter injection then MyObj needs to have a setter setExtObj. If you use constructor injection MyObj needs to have a constructor taking an instance of the ExtObj class.
Of course you can inject a 3rd party library, as long as it has constructors that Spring can access.
You can use either XML or annotations - your choice.
You need to ask Spring to instantiate the instance(s) of the library class and then inject that into your objects that need them.
You do this every time you create a Spring data source that uses a JDBC driver. That's a 3rd party library.
I am new to Spring and i am stuck with a scenario where i need help.
My Scenario is i have a bean definition for some specific module like this.
<bean name="ruleEngineAction" class="com.xxxxx.yyyy.UserAction" scope="prototype">
<property name="userManager">
<ref bean="userManager" />
</property>
<property name="userDto">
<ref bean="userDto" />
</property>
</bean>
now within this bean i want to use one more property but that depends on the application flow like
<property name="roleManager">
<ref bean="roleManager">
</property>
so should i include this property with in the bean definition itself or i can do it dynamically in code because i don't want this property to be used a lot.
Please suggest me the right and efficient approach.
From what I understood from question, there is only one bean of type roleManager but the usage of roleManager is based on application flow.
In this scenario, I would recommend you to inject roleManager to ruleEngineAction as you would do with any other bean but use the bean only when it is necessary.
It is a bad practice to needless dependency to spring in normal classes like adding reference to applicationContext for fetching the bean dynamically at runtime.
Whether or not, you inject this bean, it'll anyways be created by Spring. Why not just include the property in your UserAction and whether to use it or not, can be decided in your class. No harm in having the bean injected, because you'll anyways use it for some scenarios.
Had the scenario been like, the object won't be created, if you don't inject/use, then it would make sense to consider this situation, but since Spring will create the object anyways, it really shouldn't be a problem to just inject it.
Well you need to add new property with getter and setter in your class com.xxxxx.yyyy.UserAction for roleManager like :
class UserAction {
// your previous properties userManager, userDto, etc.
private RoleManager roleManager; // assuming interface/class as RoleManager for roleManager
// getter and setter for roleManager
// your other action methods which will use roleManager
}
There is no problem if you inject also.Whenever you access that class only it will create the object of that class.
I Am very new to Spring. I have an Interface (MessageHandler ) which has a get method, this method returns a list of Implementations of another interface (messageChecker).
public interface MessageHandler {
public void process(BufferedReader br);
public void setMessageCheckerList(List mcList);
[B]public List getMessageCheckerList();[/B]
}
In my Spring XML configuration , i have something like this ,along with other beans
<bean id="messageHandler" class="com.XXX.messagereceiver.MessageHandlerImpl">
<property name="messageCheckerList" ref="checkerList"/>
</bean>
<bean id="checkerList" class="java.util.ArrayList">
<constructor-arg>
<list>
<ref bean="HL7Checker"/>
</list>
</constructor-arg>
</bean>
<bean id="HL7Checker" class="com.XXX.messagereceiver.HL7CheckerImpl">
<property name="messageExecutor" ref="kahootzExecutor"/>
</bean>
Here i am passing a checkerlist - which is a list of Implementations ( For now i have only 1) of the Interface (messageChecker)
Checkerlist is containing references to Bean Id's which are actual implementaions.
HL7Checker is an implementation of an Interface messageChecker.
But when i run the main program, When i inject the bean "messageHandler" and call the getMessageCheckerList, It returns a null value. These getter and setter methods are working fine without using spring.
I am not sure what seems to be the problem.
I don't know the answer for you troubles, but I would check:
is the setter setMessageCheckerList(List) in messageHandler bean called? (either using some debugger or some trace output like System.out...). If it's not, there's probably something wrong with your Spring XML configuration setup. The bean definition you posted requires the property to be set and Spring wouldn't create the messageHandler bean without setting the property.
who calls the setMessageCheckerList(List) setter? Or even more precise, what code writes to the field which stores the value of the property? Maybe the field is initialized properly by Spring but gets overwritten to null later on?
are you sure you call the getMessageCheckerList on the very same object Spring has configured for you (that is, the messageHandler bean). The definition you have posted clearly states an instance of MessageHandlerImpl is created by Spring, but it doesn't prevent other instances to be created in other ways. So maybe the instance created by Spring holds the proper value, but you run the get... on a wrong instance?
I read about Compound property names in the "The Spring Framework (2.5) - Reference Documentation - chapter 3.3.2.7"
Can i use the same concept to set values of properties? Can i use a compound string as a value expression?
<bean id="service1" class="a.b.c.Service1Impl" scope="prototype">
<property name="service2" ref="service2"/>
<property name="service2.user" value="this-service1-instance.user"/>
</bean>
<bean id="service2" class="a.b.c.Service2Impl" scope="prototype">
...
</bean>
User is a property of a.b.c.Service1Impl which is not in control of Spring. I want to forward this property to a.b.c.Service2Impl.
Rather than use a plain old factory bean, rather use a factory method to create the bean of the property and then inject that result...
iow
in your case, it would look something like this...
<!-- the bean to be created via the factory bean -->
<bean id="exampleBean"
factory-bean="serviceLocator"
factory-method="createInstance"/>
So the bean of id is created by calling createInstance on bean serviceLocator.
Now spring does not support nested properties out of the box, though you could look at creating a custom editors which might provide that support - possible but tricky. Possibly not worth the effort.
One mechanism you could look at using is nesting using the factory-bean factory-method technique...
Something like:
<bean id="c" class="C" />
<bean id="b" factory-bean="c" factory-method="getB"/>
<bean id="a" factory-bean="b" factory-method="getA"/>
This will effectively expose: a.b.c where C has a method getB and A has a method getB
I had to do something similar, and I'm afraid it's not possible. I had to write a [FactoryBean][1] to expose the property.
It would look something like this:
public class UserFactory implements BeanFactory {
private Service2 service2;
// ... setter and getter for service2
public Object getObject() {
return getService2().getUser();
}
public Class getObjectType() {
return User.class;
}
public boolean isSingleton() {
// Since it's a prototype in your case
return false;
}
}
Come to think of it, in your case, you'd probably define the factory itself as a prototype, in which case your isSingleton() may return true, you'll need to play around with this a little bit.
Spring's XML wiring syntax supports lists, maps and properties objects, and you can create other 'data' objects via property editors.
Edit: (Oh I see what you are asking.) I think that the answer is no. I don't recall having seen any mention of calling getters on a bean or non-bean object in the Spring documentation, let alone a syntax for doing this in the wiring file. It tends to go against the grain. Spring wiring is declarative, and calling a getter would lead to patterns that are bordering on procedural.