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
Related
Currently I use the following method to inject properties into beans:
app.properties:
SingletonBean.valueA=this is a value
spring.xml:
<context:property-placeholder location="classpath:app.properties"/>
<context:component-scan base-package="..."/>
SingletonBean.java:
#Component
public class SingletonBean {
#Value("${SingletonBean.valueA}")
private String valueA;
}
This works great and is extremely convenient to be able to keep all my configs in a single, simple properties file. Is there any way I could extend this to work with multiple Beans of the same class? I need to do the following, with the 2 beans having different properties:
#Autowired private SampleBean beanA;
#Autowired private SampleBean beanB;
I know I can use the #Qualifier(name=...) annotation to support the following xml:
<bean id="beanA" class="SampleBean">
<property name="key1" value="A1"/>
<property name="key2" value="A2"/>
</bean>
<bean id="beanB" class="SampleBean">
<property name="key1" value="B1"/>
<property name="key2" value="B2"/>
</bean>
But with this I am forced to use old style setters in my SampleBean class, where I would prefer to use the newer #Value annotations.
Anyone know of a way to accomplish what I want that remains most consistent with how I am currently injecting my other beans?
The simple solution is just to inject all of the properties into the bean that utilizes the 2 SampleBean instances and create them with new instead. In my real code however there are actually 3 instances, each with 15 or so properties. This is much more cruft and repetition than I would like.
I have a problem with my code trying to generate #Autowired.
The Class:
public class ConsultasMDMWSClientImpl implements ConsultasMDMWSClient {
#Autowired
ConsultasMDMWSPortype consultasMDMWSPortype;
public ConsultarClienteResponseMDM consultarClienteEnMdm(ConsultarClienteRequest clienteReq) {
ConsultarClienteResponseMDM response = new ConsultarClienteResponseMDM();
ConsultasMDMWSService consultasMDMWSService = new ConsultasMDMWSService();
ConsultarClienteResponse clienteResp = null;
clienteResp = consultasMDMWSPortype.consultarCliente(clienteReq);
ListaCursoresMDM listaCursores;
listaCursores = new ObjectMapper().readValue(clienteResp.getListaCursoresResponse(), ListaCursoresMDM.class);
response.getListaCursoresResponse().add(listaCursores);
return response;
}
}
My applicationContext.xml
<context:annotation-config/>
<context:component-scan base-package="pe.com.claro.eai.esb.ws.jira.mdm"/>
<import resource="wsclients-config.xml"/>
My wsclients-config.xml
<bean id="consultasMDMWSPortype" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="serviceInterface" value="pe.com.claro.eai.consultasmdmws.ConsultasMDMWSPortype"/>
<property name="wsdlDocumentUrl" value="http://limdeseaiv28.tim.com.pe:8909/ConsultasMDMWS/ConsultasMDMPortSB11?wsdl"/>
<property name="namespaceUri" value="http://eai.claro.com.pe/ConsultasMDMWS"/>
<property name="serviceName" value="ConsultasMDMWSService"/>
<property name="portName" value="ConsultasMDMPortSB11"/>
<property name="lookupServiceOnStartup" value="false"/>
</bean>
<bean id="consultasMDMWSClient"
class="pe.com.claro.eai.esb.ws.jira.mdm.service.client.ConsultasMDMWSClientImpl">
<property name="consultasMDMWSPortype" ref="consultasMDMWSPortype"/>
</bean>
I don't know what I'm doing wrong, I've mapped everything like an example of my work
I'm new on Spring, my web method works without Spring.
The error just appear when I use #Autowired.
java.lang.NullPointerException
Thaks everyone.
As an alternative to solution proposed by #Christopher, if you want to keep the "old-style" XML configuration injection (setter injection) you need to remove #Autowired annotation and declare a setter to ConsultasMDMWSPortype, ie:
ConsultasMDMWSPortype consultasMDMWSPortype;
and
public ConsultasMDMWSPortype setConsultasMDMWSPortype(ConsultasMDMWSPortype consultasMDMWSPortype) {
this.consultasMDMWSPortype = consultasMDMWSPortype;
}
So spring will be able to wire the ref-bean configured in xml, through the setter method.
You can try to add #Component annotation on top of ConsultasMDMWSClientImpl class.
Like:
#Component
public class ConsultasMDMWSClientImpl implements ConsultasMDMWSClient {
This is needed to indicate that this is a spring bean, so that the spring container scan it and initialize as a spring bean while starting the spring container.
I hope it helps.
As already pointed out, you're mixing XML wiring with annotation wiring. The simplest solution is to take away the #Autowired of the Portype and instead inject ConsultasMDMWSClient in other beans:
#Controller
public class MyController {
#Autowired
ConsultasMDMWSClient client;
}
Another solution would be remove the wiring in XML and just inject portype in your client:
#Component
public class ConsultasMDMWSClientImpl implements ConsultasMDMWSClient {
#Resource
protected ConsultasMDMWSPortype consultasMDMWSPortype;
}
Once again, you inject the client in other beans.
In any case, you shouldn't be hardwiring the JAX-WS settings in literals, you should replace them with values in properties files and prepare different properties files for different environments. For example:
<bean id="consultasMDMWSPortype" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="serviceInterface" value="${jaxws.serviceInterface}"/>
<property name="wsdlDocumentUrl" value="${jaxws.wsdlDocumentUrl"/>
</bean>
Just replaced #Autowired by #Qualifier.
Thanks for the help.
I have a follofing situation int "super-context.xml":
<bean id="conf" class="ee.Conf"/>
<bean id="service" class="ee.Serivce">
<property name="conf" ref="conf">
</bean>
Now I want to use this "super-context.xml" in various different projects. Say "sub-context.xml" has:
<import resource="super-context.xml"/>
<bean id="subConf1" class="ee.SubConf">
<property name="confloc" value="classpath:ee/customconf1.sss" />
</bean>
<bean id="subConf2" class="ee.SubConf">
<property name="confloc" value="classpath:ee/customconf2.sss" />
</bean>
...
<bean id="subConfn" class="ee.SubConf">
<property name="confloc" value="classpath:ee/customconfn.sss" />
</bean>
ee.Conf is something as follows:
public class Conf ... {
...
public void addSubConf(Resource res) {
//configuration resolving from res
}
...
}
ee.SubConf is something as follows:
public class SubConf ... {
...
#Autowired
ee.Conf superConf;
...
public void setConfloc(Resource res) {
superConf.addSubConf(res);
}
...
}
The problem aries on context load. Beans are initialized in following order (due to ordering in context file): conf, service, subConf1, subConf2, ... subConfn
But service bean actually depends on all the subConf beans (although this can't be deducted from the context definition itself). It loads OK when import in "sub-context.xml" is added after subConf bean definitions.
Reason behind this is implementing modularity. Is it possible to force a bean to load as late as possible ("service" bean in the example) or make beans of certain type load as soon as possible ("subConf" beans in the example), since fixed ordering of beans in "sub-context.xml" partly kills the wished modularity
Or is theree a more pure way to achieve this type of modularity?
I would say that you are approaching the problem in a wrong way. The SubConf shouldn't have a dependency on the Conf to start with. Simply inject the collection of SubConf objects in your Conf object.
public class Conf {
#Autowired
private List<SubConf> subconfs;
}
That way you eliminate the need for the SubConf to call the Conf class and this will remove your circular dependency.
See the Spring reference guide for more information on autowiring.
You can use depends-on
<bean id="beanOne" class="foo.Bar" depends-on="beanTwo" />
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.
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.