Reputation: 107
I am trying to implement a spring email service for which I implemented the GOOF design pattern. I created an interface Email service as follows.
public interface EmailService {
public void sendFeedbackEmail(FeedbackPojo feedbackPojo);
public void sendGenericEmailMessage(SimpleMailMessage message);
}
Then I created an abstract class which extends this interface and implements one of it's overridden methods which is sendFeedbackEmail(FeedBackPojo feedbackpojo)
The implementation of this abstract class is as follows.
public abstract class AbstractEmailService implements EmailService {
@Value("@{default.to.address}")
private String defaultToAddress ;
protected SimpleMailMessage preparedSimpleMailMessageFromFeedbackPojo(FeedbackPojo feedback){
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(defaultToAddress);
message.setFrom(feedback.getEmail());
message.setSubject("[Subscriber]: Feedback Received from"+ feedback.getFirstName()+" "+feedback.getLastName()+"!");
message.setText(feedback.getFeedback());
return message;
}
@Override
public void sendFeedbackEmail(FeedbackPojo feedbackPojo) {
sendGenericEmailMessage(preparedSimpleMailMessageFromFeedbackPojo(feedbackPojo));
}
}
Then I created a class MockEmailService with the implementation of second method of the EmailService interface which is sendGenericEmail(SimpleMailMessage message) as follows
public class MockEmailService extends AbstractEmailService{
private static final Logger log =
LoggerFactory.getLogger(MockEmailService.class);
@Override
public void sendGenericEmailMessage(SimpleMailMessage message) {
System.out.println(message.toString());
}
}
Then I am creating an Autowired object of emailService in my controller class and simulating my emailservice as follows
@Controller
public class ContactController {
private static final org.slf4j.Logger log = LoggerFactory.getLogger(ContactController.class);
public static final String FEEDBACK_MODEL_KEY="feedback";
private static final String CONTACT_US_VIEW_NAME="contact/contact";
@Autowired
private EmailService emailService;
@RequestMapping(value = "/contact",method = RequestMethod.GET)
public String getContact(ModelMap model){
FeedbackPojo feedbackPojo = new FeedbackPojo();
model.addAttribute(ContactController.FEEDBACK_MODEL_KEY,feedbackPojo);
return ContactController.CONTACT_US_VIEW_NAME;
}
@RequestMapping(value = "/contact",method = RequestMethod.POST)
public String postContact(@ModelAttribute(FEEDBACK_MODEL_KEY) FeedbackPojo feedback){
log.debug("Feedback content {}",feedback);
emailService.sendFeedbackEmail(feedback);
return ContactController.CONTACT_US_VIEW_NAME;
}
}
However, when I try to run my application the application terminates and the error I receive is as follows
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contactController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.subscriptionservice.backend.service.EmailService com.subscriptionservice.web.controllers.ContactController.emailService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.subscriptionservice.backend.service.EmailService] 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)}
Can someone please point out the issue in my implementation. Thanks.
Upvotes: 1
Views: 570
Reputation: 8446
No qualifying bean of type [com.subscriptionservice.backend.service.EmailService] found for dependency
As far as I see, you haven't introduced an instance of your interface EmailService
into the collection of Spring-managed beans.
Try annotating (stereotyping) the MockEmailService
with @Service
.
Also...
component-scan
defined somewhere in a manner that will include the package where MockEmailService
resides.MockEmailService
will permanently implement the contract of EmailService
in your application? (Based on the name, I wouldn't guess so.) If MockEmailService
is intended only for certain circumstances -- such as non-production deployments or testing -- you may need a more flexible system for defining or wiring your beans. There are many options, such as Spring Profiles.Upvotes: 4