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..
}
When @Autowired doesn't work. There are several reasons @Autowired might not work. When a new instance is created not by Spring but by for example manually calling a constructor, the instance of the class will not be registered in the Spring context and thus not available for dependency injection.
To diagnose this type of issue, we'll first make sure the bean is declared: either in an XML configuration file using the <bean /> element. or in a Java @Configuration class via the @Bean annotation. or is annotated with @Component, @Repository, @Service, @Controller, and classpath scanning is active for that package.
The Spring framework enables automatic dependency injection. In other words, by declaring all the bean dependencies in a Spring configuration file, Spring container can autowire relationships between collaborating beans. This is called Spring bean autowiring.
The field annotated @Autowired is null because Spring doesn't know about the copy of MileageFeeCalculator that you created with new and didn't know to autowire it.
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.
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With