When Maven kicked off in 2002, it strongly looked for an IoC or a DI framework. As we discussed before, Maven provides a build framework while the actual work is done by the components and plugins developed on top of it. That's part of the Maven's design philosophy, and this raised the need to have some kind of a component framework to bring in plugins and other extensions.
By 2002, Spring was not that popular and Apache Avalon was the only IoC framework out there. However, the initial set of Maven committers, who also had a strong influence on Plexus, decided to use it as the IoC container for Maven.
Plexus did exactly what Maven wanted to have. However, it uses its own custom DI mechanism. In November 2009, the Java community standardized DI via JSR 330 (https://www.jcp.org/en/jsr/detail?id=330). Maven 3.0 onwards started supporting JSR 330 via Google Guice (https://github.com/google/guice). Then again, the components that were written using Plexus APIs could still coexist with JSR 330 compliant components and plugins.
To know more about Maven and Google Guice, refer to From Plexus to Guice (#1): Why Guice? at http://blog.sonatype.com/2010/01/from-plexus-to-guice-1-why-guice.
Google Guice is a lightweight DI framework that has support for JSR 330. Guice was initially developed by Google under the leadership of Bob Lee. He currently works as the CTO of Square and was the lead of JSR 330.
Let's rewrite the same example we did with Plexus in Guice, to be JSR 330 compliant, as follows:
package com.packt.di; public interface MessagingService { public void sendMessage(String recipient, String message); }
SMSMessagingService
class will text the message to the recipient, while the EmailMessagingService
class will email the message, shown as follows:package com.packt.di; public class SMSMessagingService implements MessagingService{ @Override public void sendMessage(String recipient, String message) { System.out.println("SMS sent to : "+recipient); } } package com.packt.di; public class EmailMessagingService implements MessagingService{ @Override public void sendMessage(String recipient, String message) { System.out.println("Email sent to : "+recipient); } }
GuiceMessageSender
class, which will dynamically pick the MessagingService
implementation to send the message, shown as follows. The Guice framework will inject the implementation class instance into the method that has the Inject
annotation:package com.packt.di; import javax.inject.Inject; public class GuiceMessageSender { private MessagingService messagingService; @Inject public void setService(MessagingService messagingService) { this.messagingService = messagingService; } public void sendMessage(String recipient, String message) { messagingService.sendMessage(recipient, message); } }
AbstractModule
class of the com.google.inject
package, which will bind an implementation class to the interface, as follows:package com.packt.di; import com.google.inject.AbstractModule; public class GuiceInjector extends AbstractModule { @Override protected void configure() { bind(MessagingService.class).to(SMSMessagingService.class); } }
GuiceClientApplication
class will send the message using an instance of the GuiceMessageSender
class, as follows. You can download all the dependency JARs from https://svn.wso2.org/repos/wso2/people/prabath/maven/chapter05/guice/lib:package com.packt.di; import com.google.inject.Guice; import com.google.inject.Injector; public class GuiceClientApplication { public static void main(String[] args) { Injector injector; GuiceMessageSender messageSender; injector = Guice.createInjector(new GuiceInjector()); messageSender = injector.getInstance(GuiceMessageSender.class); messageSender.sendMessage("+94718096732", "Welcome to Plexus"); } }
The complete Java project used here can be downloaded from https://svn.wso2.org/repos/wso2/people/prabath/maven/chapter05/guice.
18.188.187.165