Reputation: 5867
I am trying to implement email functionality in my app but I keep getting
No matching bean of type [org.springframework.mail.javamail.JavaMailSenderImpl] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
Can anyone point out what I am doing incorrectly?
The xml config for the bean is:
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<context:annotation-config/>
//...other stuff
<beans:bean id="mailSession" class="org.springframework.jndi.JndiObjectFactoryBean">
<beans:property name="jndiName" value="EmailServer" />
</beans:bean>
<beans:bean id="emailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<beans:property name="session" ref="mailSession"/>
</beans:bean>
EmailServiceImpl class:
@Service
public class EmailServiceImpl implements EmailService {
@Autowired
private JavaMailSenderImpl emailSender;
//more code..
}
Upvotes: 6
Views: 12765
Reputation: 8310
I was struggling with this very problem for an email service class coded like:
@Service("emailService")
public class EmailService {
@Autowired private JavaMailSenderImpl mailSender;
...
public void send(...) {
// send logic
}
}
I stumbled across a solution while reading about a related topic. The key point is that JavaMailSender
interface is defined in the applicationContext.xml
as the Spring JavaMailSenderImpl
class.
Step 1: The application context file was modified to include the following bean definition:
<bean id="mailSender"
class="org.springframework.mail.javamail.JavaMailSenderImpl"
p:host="myMailserver.mycompany.com" />
Step 2: The email service class was modified to look like:
@Service("emailService")
public class EmailService {
@Autowired private JavaMailSender mailSender; // Observe the change in the type
...
Voila! Spring is happy. I would though like to hear a proper explanation of the original error.
Upvotes: 4
Reputation: 13419
This is how I fixed it:
I ran into this issue too, I tried to follow simple tutorials online that worked perfectly during testing by loading the app-context.xml file manually but when I tried to run my spring mvc app it kept showing this error:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.springframework.mail.javamail.JavaMailSender] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:952)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:821)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:735)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
... 42 more
After trying all kinds of things, I happened to move these two lines from my JPA/DB configuration file to the bottom of my root-config file.
<context:annotation-config/>
<context:component-scan base-package="my.app.service.layer"/>
I'm still learning Spring but I'm thinking there was an issue regarding the order in which they appear.
Edit: This question seems to clarify the issue with the order:
Difference between applicationContext.xml and spring-servlet.xml in Spring Framework
Upvotes: 1
Reputation: 5867
Thanks to everyone for their responses. I was unable to get the autowiring to work, but I got the overall email solution to work by doing the following:
add to servlet-context.xml:
<beans:bean id="mailSession" class="org.springframework.jndi.JndiObjectFactoryBean">
<beans:property name="jndiName" value="myMailSession" />
</beans:bean>
<beans:bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<beans:property name="session" ref="mailSession"/>
</beans:bean>
<beans:bean id="emailServiceImpl" class="com.name.here.business.EmailServiceImpl">
<beans:property name="mailSender" ref="mailSender"/>
</beans:bean>
add to web.xml:
<resource-ref>
<description>the email session</description>
<res-ref-name>myMailSession</res-ref-name>
<res-type>javax.mail.Session</res-type>
<res-auth>Container</res-auth>
</resource-ref>
add to weblogic.xml:
<resource-description>
<res-ref-name>myMailSession</res-ref-name>
<jndi-name>myMailSession</jndi-name>
</resource-description>
EmailServiceImpl:
@Service
public class EmailServiceImpl implements EmailService {
private JavaMailSender mailSender;
public void setMailSender(JavaMailSender mailSender) {
this.mailSender = mailSender;
}
//..other code
}
Upvotes: 2
Reputation: 21
Do you have a @Service or similar annotation on your JavaMailSenderImpl class itself? This will cause Spring's component scanner to put an instance of it in the spring container, which it can then autowire onto the EmailServiceImpl.
Upvotes: 1
Reputation: 3975
From error message, I can conclude that autowiring is working , but its not able to find the required bean.
Make sure you load all the bean definition files.
Upvotes: 1
Reputation: 336
You need to add <context:annotation-config/>
to your config file in order for Spring to autowire annotated beans.
http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config
Upvotes: 1