- Download Guice from the Guice Site.
- Create the Service Interface and Implementation: These are fairly simple as shown below
package services;
public interface Service {
public String doWork();
}Service.java package services;
public class ServiceImpl implements Service {
private int count = 0;
public String doWork() {
count++;
System.out.println("Service Impl Doing work " + count);
return("ServiceImpl : " + count);
}
}ServiceImpl.java - Create an Annotation: Guice allows you to select which implementation of an Interface you want to inject, by using annotations. You will see this used in the TestServlet. Here is the annotation I defined
package annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.google.inject.BindingAnnotation;
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.FIELD, ElementType.PARAMETER })
@BindingAnnotation
public @interface MyAnnotation {
}MyAnnotation.java - @Rentention(RUNTIME) makes the annotation visible at runtime.(this is mandatory when using Guice)
- @Target({FIELD, PARAMETER}) prevents the annotation from being applied to methods, types, local variables, and other annotations.(This is optional)
- @BindingAnnotation is a Guice-specific signal that you wish your annotation to be used in this way. Guice will produce an error whenever user applies more than one binding annotation to the same injectable element. (This is necessary when used for binding with Guice)
- Optionally, you can also use annotations with attributes to differentiate between bindings.
- Create a Guice Module: Guice Modules are used to define bindings within an applications. It is possible to have multiple modules per application (and multiple applications can share a common module too). Here is the simple Module that I implemented.
package modules;
import services.Service;
import services.ServiceImpl;
import annotations.MyAnnotation;
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
public class MyModule extends AbstractModule {
public void configure() {
bind(Service.class).annotatedWith(MyAnnotation.class).to(ServiceImpl.class).in(Scopes.SINGLETON);
}
}MyModule.java - Guice provides the module with a binder which is used to bind the Interfaces with implementations.
- annotatedWith(MyAnnotation.class) defines the binding to the implementation based on the annotation.
- in(Scopes.SINGLETON) is used to define this implementation as a Singleton
- Create a Listener: Here is the Code for a simple listener (for a more complete example see the above mentioned mailing list).
package listeners;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import modules.MyModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.servlet.ServletModule;
public class GuiceServletContextListener implements ServletContextListener {
public void contextDestroyed(ServletContextEvent servletContextEvent) {
ServletContext servletContext = servletContextEvent.getServletContext();
servletContext.removeAttribute(Injector.class.getName());
}
public void contextInitialized(ServletContextEvent servletContextEvent) {
Injector injector = Guice.createInjector(new Module[] { new MyModule(), new ServletModule() });
ServletContext servletContext = servletContextEvent.getServletContext();
servletContext.setAttribute(Injector.class.getName(), injector);
}
}GuiceServletContextListener.java - The listener is used to save the Injector in the servlet context to be used in the AbstractInjectableServlet.
- An injector is to be built during startup and used to inject objects at runtime.
- ServletModule is used for servlet-specific bindings. It adds a request/session scope, as well as allowing the injection of request,response, and request parameters into your beans. To use it you have to register GuiceFilter in your web.xml.
- Create an Abstract Servlet: The AbstractInjectableServlet will be super class of all the Servlets you use. This class uses the injector to inject dependencies in the concrete classes by the injector.injectMembers(this) method.
package servlets;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import com.google.inject.Injector;
public abstract class AbstractInjectableServlet extends HttpServlet {
@Override
public void init(ServletConfig config) throws ServletException{
ServletContext context = config.getServletContext();
Injector injector = (Injector) context.getAttribute(Injector.class.getName());
if (injector == null) {
throw new ServletException("Guice Injector not found");
}
injector.injectMembers(this);
}
}AbstractInjectableServlet.java - Create the Test Servlet: Here is the code for the TestServlet
package servlets;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import services.Service;
import annotations.MyAnnotation;
import com.google.inject.Inject;
public class TestServlet extends AbstractInjectableServlet implements javax.servlet.Servlet {
private Service service;
public TestServlet() {
super();
}
@Inject
public void setServiceInstance(@MyAnnotation Service service) {
this.service = service;
}
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("Service instance : " + service.doWork());
}
}TestServlet.java - The @Inject is used to define methods to be injectable.
- The @MyAnnotation for the Service parameter means that, the actual binding will be done with the implementation that is bound using the withAnnotation() method.
- The Web Deployment Descriptor
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>GuiceWeb</display-name>
<listener>
<listener-class>listeners.GuiceServletContextListener</listener-class>
</listener>
<servlet>
<description></description>
<display-name>TestServlet</display-name>
<servlet-name>TestServlet</servlet-name>
<servlet-class>servlets.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>/testServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>web.xml
Thursday, March 15, 2007
My First Guice Web Application
Google Guice is an open source Dependency Injection framework from Google. Guice is based on annotations and generics unlike Spring which depends on XML of Java for wiring dependencies. Guice injects constructors, fields and methods (any methods with any number of arguments, not just setters). Guice provides support for custom scopes, static member injection, Spring as well as Struts 2.x integration and AOP Alliance method interception. Guice is available at Google Code. You can find the User guide and Javadocs from there. This post describes how I implemented a simple Web application using Guice. For injecting dependencies into Servlets, I used a Listener (this idea was from Hani Suleiman in the Guice developer mailing list). Follow these steps to run the example.
Subscribe to:
Post Comments (Atom)
Popular Posts
-
The previous post described how to implement a JMS messaging client using Spring JMS . This post will describe how to implement the Message ...
-
JUnit 4 introduces a completely different API to the older versions. JUnit 4 uses Java 5 annotations to describe tests instead of using in...
-
In the past, I had a few posts on how to implement pagination using displaytag( 1 , 2 ). That solution is feasible only with small result se...
-
This post will describe how to create and deploy a Java Web Application war to Heroku using Heroku CLI. You will need a basic understanding ...
-
New posts with iText 5.5.12 Following are two new posts for PDF Merge with iText 5.5.12 Merge PDF files using iText 5 Merge and Paginate PDF...
-
Recently I was attempting to deploy to weblogic from a Jenkins installed on a Red Hat Enterprise Linux Server release 7.3 , to a remote Webl...
-
WebLogic Server does not support or certify any particular LDAP servers. Any LDAP v2 or v3 compliant LDAP server should work with WebLogic ...
-
The example here demonstrates the use of an anonymous PL/SQL block to return data to a calling Java program. It also shows how to use nested...
-
The String class doesn't have the ability to compare text from a natural language perspective. Its equals and compareTo methods compa...
-
In this post we will see how to do an offline install Jenkins and required plugins on a Red Hat Enterprise Linux Server release 7.3. This is...
I know it isn't directly relevant to Guice, but the ServiceImpl class is not thread-safe: the count field is accessed without any kind of synchronization. A simple way to fix it would be to wrap the counter increment in a synchronized block like this:
ReplyDeleteint c;
synchronized (this) { c = count++; }
and use c instead of count in the trace message and the returned string.
Tim Peierls
Well, this is a nice thing to get some articles collected from various sites. but I think the owner of this blog should give some examples rather than copy/ paste.
ReplyDeletesomething is burning...ego hurted....:)))
Thank very much Abhi is just that i looking for! great post!
ReplyDeleteGood Job Abhi Good effort All the best- Blogger Chaala Bagundi :)
ReplyDeletethe AbstractInjectableServlet class is already implemented in Guice and teh class is com.google.inject.servlet.InjectedHttpServlet
ReplyDeletewarp-servlet provides a much nicer version of injectable servlets, as it stands neither AbstractInjectableServlet nor InjectedHttpServlet are capable of:
ReplyDeleteconstructor injection
aop interception
cyclical ctor injection
scoping
warp-servlet allows your servlets and filters to benefit from all of this, and more scopes.
Hi,
ReplyDeleteI found your article excellent and in my company (www.asemantics.com) we used your example as a startup for our application.
Congratulations!
Simone
I guess you could omit the ElementType.PARAMETER for MyAnnotation because you only use it on a parameter. BTW you can also do constructor and local variable annotations accordingly.
ReplyDeleteI am Aditi webmaster of Zed-Axis Technologies Pvt. Ltd Software Development Company Microsoft Certified, IT Solutions Company, offering Custom Software application development and web site development in India.
ReplyDeleteWhen i read your article i feel its good keep it up.
ReplyDeleteHigh Quality java application & java web Development Company in Australia
It is great to read article about web application development.
ReplyDeleteWeb Application Development Company
It’s really awesome article they provide lot of information.
ReplyDeleteCutting edge mobile app Development Company
It’s really awesome article they provide lot of information.
ReplyDeleteSchool Application Development in Sydney
Thanks for providing valuable information on Java web application.
ReplyDeleteLeading website development company in Nagpur
Thanks for providing valuable information.
ReplyDeleteIf your interested app development please connect us on SSI!
I am here after long google. thanks for this post.
ReplyDeleteIf you interested app development please connect us on Sagacity Solutions India
Impressive!Thanks for the post
ReplyDeleteBest Travel Agency in Madurai | Travels in Madurai
Madurai Travels | Best Travels in Madurai
Tours and Travels in Madurai | Best Tour Operators in Madurai