I have some Abstract Factory
public interface AbstractViewersFactory {
IAbstractShapeViewer createRectangle(BaseOperationsListener<RectangleDTO> p);
IAbstractShapeViewer createOval(BaseOperationsListener<OvalDTO> p);
IAbstractShapeViewer createTriangle(BaseOperationsListener<TriangleDTO> p);
}
And Its implementation Draw2DViewersFactory.
Now, I want create some class that will take responsibility for creating presenters/viewers by model and configurate it by Spring.
So, I need describe in .xml configuration what method it should call.
It can be something like this (pseudo config)
<bean creator>
<constructor-args>
<list>
<bean describe-item> <constructor-args>model=Rectangle.class, method-for-viewer-create="createRectangle"</args>
<bean describe-item> <constructor-args>model=Oval.class, method-for-viewer-create="createOval"</args>
<list>
</constructor-args>
</bean>
How I can do it?
Thanks.
Even though your question is very unclear, I think I got what you wanted to know.
You can define a spring bean as a factory instance and then set the factory method of this bean like this:
<bean id="myFactoryBean"
class="AbstractViewersFactory">
<bean id="exampleBean"
factory-bean="myFactoryBean"
factory-method="createRectangle"/>
Hope this helps.
Google this for further information :p
greetings
Related
I need my Spring application context to include a bean that is a (Java 7) Path object, with a fixed (known) path-name. What XML bean definition should I use?
This kind of bean has some complications:
Path is an interface, and Path objects should be created using the Paths.get(String...) static factory method.
The static factory method also has an overloaded variant, Paths.get(URI).
As the object is-a Path, the class of the bean should be Path:
<bean name="myPath" class="java.nio.file.Path"/>
I need to indicate the static factory method to use, which would seem to require a factory-method attribute. But the factory method belongs to the java.nio.file.Paths class rather than the java.nio.file.Path class, so I assume the following would not work:
<bean name="myPath" class="java.nio.file.Path"
factory-method="java.nio.file.Paths.get"/>
Lastly, I need to give the arguments for the factory method. How do I do that? Using nested constructor-arg (sic) elements? So, something like this?
<bean name="myPath" class="java.nio.file.Path"
factory-method="java.nio.file.Paths.get">
<constructor-arg value="/my/path/name"/>
</bean>
But that does not work: Springs throws a BeanCreationException, complaining of "No matching factory method found: factory method 'java.nio.file.Paths.get()'."
After some experimenting with pingw33n's answer, I found this worked:
<bean id="myPath" class="java.nio.file.Paths" factory-method="get">
<constructor-arg value="/my/path" />
<constructor-arg><array /></constructor-arg>
</bean>
Note:
Give the name of the factory class, rather than the object class, as the value of the class attribute.
Give an extra empty array constructor argument, to force selection of the correct overload of the factory method. This avoids having to go the round-about route of instead constructing a file URI.
Well , i had the same problem as you , and my solution was ...
<bean id="ThreadRunnerConfigFile" class="java.nio.file.Paths" factory-method="get" c:_0="ThreadRunnerConfigFileStr" />
Dont forget to include the c namespace on your .xml configuration file
Something like below should help.
<bean id="myPath" class="java.nio.file.Paths" factory-method="get">
<constructor-arg type="java.lang.String" value="/my/path/name" />
</bean>
Try this:
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod"><value>java.nio.file.Paths.get</value></property>
<property name="arguments">
<array>
<value>/my/path/name</value>
<array/>
</array>
</property>
</bean>
I'm having some problems understanding how to use annotations, especially with beans.
I have one component
#Component
public class CommonJMSProducer
And I want to use it in another class and i thought I could do that to have a unique object
public class ArjelMessageSenderThread extends Thread {
#Inject
CommonJMSProducer commonJMSProducer;
but commonJMSProducer is null.
In my appContext.xml I have this :
<context:component-scan base-package="com.carnot.amm" />
Thanks
You have to configure Spring to use this autowiring feature:
<context:annotation-config/>
You can find the details of annotation-based config here.
ArjelMessageSenderThread also have to be managed by Spring otherwise it won't tamper with its members since it does not know about it.
OR
if you cannot make it a managed bean then you can do something like this:
ApplicationContext ctx = ...
ArjelMessageSenderThread someBeanNotCreatedBySpring = ...
ctx.getAutowireCapableBeanFactory().autowireBeanProperties(
someBeanNotCreatedBySpring,
AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT, true);
OR
as others pointed out you can use annotations to use dependency injection on objects which are not created by Spring with the #Configurable annotation.
It depends on how you create instances of ArjelMessageSenderThread.
If ArjelMessageSenderThread is a bean that should be created by spring you just have to add #Component (and make sure the package is picked up by the component scan).
However, since you extend Thread, I don't think this should be a standard Spring bean. If you create instances of ArjelMessageSenderThread yourself by using new you should add the #Configurable annotation to ArjelMessageSenderThread. With #Configurable dependencies will be injected even if the instance is not created by Spring. See the documentation of #Configurable for more details and make sure you enabled load time weaving.
I used XML instead of annotations. This seemed difficult for not a big thing. Currently, I just have this more in the xml
<bean id="jmsFactoryCoffre" class="org.apache.activemq.pool.PooledConnectionFactory"
destroy-method="stop">
<constructor-arg name="brokerURL" type="java.lang.String"
value="${brokerURL-coffre}" />
</bean>
<bean id="jmsTemplateCoffre" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref local="jmsFactoryCoffre" />
</property>
</bean>
<bean id="commonJMSProducer"
class="com.carnot.CommonJMSProducer">
<property name="jmsTemplate" ref="jmsTemplateCoffre" />
</bean>
And another class to get the bean
#Component
public class ApplicationContextUtils implements ApplicationContextAware {
Thanks anyway
Reading the doc about configuring a defaultUri (http://docs.spring.io/spring-ws/site/reference/html/client.html) I have this :
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="messageFactory"/>
<property name="defaultUri" value="http://example.com/WebService"/>
</bean>
I want to amend the property defaultUri so that it is read from a property configured in a different bean.
I could use something like :
<bean id="myBean" class="org.myBean" "factory-method=getDefaultUri"/>
the bean class "myBean" is then defined like :
public class myBean {
public String getDefaultUri(){
///invoke other method which get the URI
return "myUri"
}
}
So basically I want to configure the defaultUri using a property.
Are there other implementations other than what I outlined ?
Take a look at BeanPostProcessor interface, I believe is what you are looking for ... I use to do some processing in a scenario like this...
public interface BeanPostProcessor
"Factory hook that allows for custom modification of new bean
instances, e.g. checking for marker interfaces or wrapping them with
proxies."
More info: http://docs.spring.io/spring/docs/3.0.x/api/org/springframework/beans/factory/config/BeanPostProcessor.html
In Spring I can define a HashSet like so in XML:
<bean id="subscriberStore" class="java.util.HashSet"/>
And, I can do the following in the code to create a concurrent hash set:
subscriberStore = Collections.newSetFromMap(
new ConcurrentHashMap<Subscriber, Boolean>());
But is there any way I can do this in one step in the XML? E.g. something like:
<bean id="subscriberStore" class="java.util.HashSet"/>
< Some code here to set subscriberStore to the result
of Collections.newSetFromMap(new ConcurrentHashMap<Subscriber, Boolean>? >
Many Thanks!
Bean configuration:
<!-- The bean to be created via the factory bean -->
<bean id="exampleBean"
factory-bean="myFactoryBean"
factory-method="createInstance"/>
<bean id="myFactoryBean" class="com.rory.ConcurrentHashMapFactory"/>
And the factory class:
public class ConcurrentHashMapFactory {
public Set<Subscriber> createInstance() {
Collections.newSetFromMap(new ConcurrentHashMap<Subscriber, Boolean>());
}
}
You could use something like the following:
<bean
id="subscriberStore"
class="java.util.Collections"
factory-method="newSetFromMap"
>
<constructor-arg>
<bean class="java.util.concurrent.ConcurrentHashMap" />
</constructor-arg>
</bean>
However, if generic types are important to you, create a custom, static factory method (as Boris Pavlović kind of suggests in his answer). You might want to take a look at this SO entry for some information regarding generics and Spring XML bean definitions.
currently I'm creating proxy classes from interfaces with spring 3 xml config like this:
<bean id="abstractDaoTarget" class="mypackage.GenericDaoImpl" abstract="true" />
<bean id="abstractDao" class="org.springframework.aop.framework.ProxyFactoryBean" abstract="true" />
<bean id="personDao" parent="abstractDao">
<property name="proxyInterfaces">
<value>mypackage.CustomerDao</value>
</property>
<property name="target">
<bean parent="abstractDaoTarget">
</bean>
</property>
</bean>
Note that I have only one interface named PersonDao and NO implementation of this interface. The above xml snippet works fine, I can create an 'instance' of the interface.
My Question is how can I achieve this with pure Spring 3 annotations without the above xml snippet?
Is it possible without xml?
Have a look at Spring Data JPA. Here's an introductory tutorial. They are doing pretty much exactly what you are.
Are you looking for an way to generate Beans with an factory completely written in Java without xml? - Then use #Configuration to annotate the class and #Bean to annotate the method that creates the bean. 3.11.1 Basic concepts: #Configuration and #Bean
If this is not what you mean, then have a look at the code of Hades. This is a project that do the same think like (I guess) you. Creating DAOs from Interfaces.