Recently, I was working on a requirement to send notifications via email and sms in my project. My initial design was to have a common interface (NotificationService) with these methods - sendNotification and validateRequest. Both the SmsNotifier and EmailNotifier would implement the interface NotificationService and access to the notification interface would be through a rest end point (post).
And
since I’d auto wired dependencies in the Resource class, I’d to figure out a
way to inject implementations dynamically. So, I opted for a factory pattern
design. This is a straight forward requirement but let’s see how to achieve
this with spring.
package com.spring.prototype.service; public interface NotificationService { String sendNotification(); } @Component("email") public class EmailNotificationService implements NotificationService { public String sendNotification() { return "Send notifications via email"; } } package com.spring.prototype.service; import org.springframework.stereotype.Component; @Component("sms") public class SmsNotificationService implements NotificationService { public String sendNotification() { return "Send notifications via sms"; } }
Solution:
ServiceLocatorFactoryBean which takes two inputs
serviceLocatorInterface
– which is responsible for creating classes based on the input
mappings
– which maps names to actual implementations.
Add
these configurations in the context xml.
Autowire
factory class instead of the interface and let the input decide which
implementation to choose.
<beans:bean class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean" id="printStrategyFactory"> <beans:property name="serviceLocatorInterface" value="com.spring.prototype.factory.NotificationFactory"> </beans:property> <beans:property name="serviceMappings"> <beans:props> <beans:prop key="email">email</beans:prop> <beans:prop key="sms">sms</beans:prop> </beans:props></beans:property> </beans:bean>
Resource Class:
------------------
@Component @Path("/notification") @Produces(MediaType.TEXT_PLAIN) public class NotificationResource { @Autowired NotificationFactory factory; @POST @Path("{type}") public String sendNotification(@PathParam("type") String type) { return factory.getNotificationService(type).sendNotification(); } }
Full project is available on github.
Note: You would actually end up writing a lot more code to send mail/sms. This post deals only with implementing a factory pattern in Spring and autowiring dependencies. Let me know what you think.
Happy coding :)
~
cheers.!
No comments:
Post a Comment