From a high level, Guice and Spring JavaConfig bring many of the same capabilities to the table. They both provide annotation-based dependency injection, they both boast simple APIs, and they both get you quickly up and running with an IoC container.
Spring JavaConfig mainly brings a new type of
ApplicationContext
into the picture, namely
JavaConfigApplicationContext
, along with various support
infrastructure including new annotations such as @Bean
,
@Configuration
, etc. Otherwise, it's still the same
familiar Spring.
Guice follows a different albeit similar model, introducing
non-Spring infrastructure including annotations, support classes, etc.
The only scent of Spring hovers around the
SpringIntegration
class.
Comparing the two side-by-side exhibits their similarities as
dependency injection frameworks, and exposes their differences as
Spring-integrable modules. This comparison includes a single interface
and implementation, called Greeter
and
DefaultGreeter
, which define and realize a simple function
called getGreeting()
which returns the obligatory
"Hello World!"
.
package com.earldouglas.guicespringjc;
public interface Greeter {
public String getGreeting();
}
package com.earldouglas.guicespringjc;
public class DefaultGreeter implements Greeter {
public String getGreeting() {
return "Hello World!";
}
}
The Guice Module
, an analog to a Spring context
configuration, simply binds the Greeter
interface to the
only implementation of DefaultGreeter
.
package com.earldouglas.guicespringjc.guice;
import com.earldouglas.guicespringjc.DefaultGreeter;
import com.earldouglas.guicespringjc.Greeter;
import com.google.inject.AbstractModule;
public class SimpleGuiceModule extends AbstractModule {
@Override
protected void configure() {
bind(Greeter.class).to(DefaultGreeter.class);
}
}
SimpleGuiceModule
is bootstrapped by creating an
Injector
. The bound Greeter
is retrieved, and
its greeting is printed.
package com.earldouglas.guicespringjc.guice;
import com.earldouglas.guicespringjc.Greeter;
import com.google.inject.Guice;
import com.google.inject.Injector;
public class SimpleGuiceBootstrapper {
public static void main(String` arguments) {
= Guice.createInjector(new SimpleGuiceModule());
Injector injector = injector.getInstance(Greeter.class);
Greeter greeter System.out.println(greeter.getGreeting());
}
}
The Spring JavaConfig Configuration
defines a
@Bean
method which returns an instance of
DefaultGreeter
.
package com.earldouglas.guicespringjc.spring;
import org.springframework.config.java.annotation.Bean;
import org.springframework.config.java.annotation.Configuration;
import com.earldouglas.guicespringjc.DefaultGreeter;
import com.earldouglas.guicespringjc.Greeter;
@Configuration
public class SimpleSpringConfiguration {
@Bean
public Greeter greeter() {
return new DefaultGreeter();
}
}
SimpleSpringConfiguration
is bootstrapped by
instantiating a JavaConfigApplicationContext
. The
Greeter
bean is retrieved, and its greeting is printed.
package com.earldouglas.guicespringjc.spring;
import org.springframework.config.java.context.JavaConfigApplicationContext;
import com.earldouglas.guicespringjc.Greeter;
public class SimpleSpringBootstrapper {
public static void main(String` arguments) {
= new JavaConfigApplicationContext(SimpleSpringConfiguration.class);
JavaConfigApplicationContext applicationContext = applicationContext.getBean(Greeter.class);
Greeter greeter System.out.println(greeter.getGreeting());
}
}
So far the configuration, bootstrapping, and interaction with both Guice and Spring JavaConfig are quite similar in complexity and nearly identical in function. Introducing a schema-based Spring context configuration will fix that.
An XML configuration which represents both the
SimpleGuiceModule
and the
SimpleSpringConfiguration
simply defines a single bean,
greeter, as an instance of DefaultGreeter
.
config.xml:
<?xml version="1.0" encoding="UTF-8"?>
beans xmlns="http://www.springframework.org/schema/beans"
< xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
bean id="greeter" class="com.earldouglas.guicespringjc.DefaultGreeter" />
<
beans> </
The Guice Module
binds the beans in Spring configuration
using SpringIntegration
.
package com.earldouglas.guicespringjc.guice;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.google.inject.AbstractModule;
import com.google.inject.spring.SpringIntegration;
public class XmlGuiceModule extends AbstractModule {
@Override
protected void configure() {
= new ClassPathXmlApplicationContext(
ApplicationContext applicationContext "com/earldouglas/guicespringjc/spring/config.xml");
.bindAll(binder(), applicationContext);
SpringIntegration}
}
XmlGuiceModule
is bootstrapped in nearly the same way as
was SimpleGuiceModule
. The difference is that the
Greeter
is retrieved by its implementation class rather
than the Greeter
interface.
package com.earldouglas.guicespringjc.guice;
import com.earldouglas.guicespringjc.DefaultGreeter;
import com.earldouglas.guicespringjc.Greeter;
import com.google.inject.Guice;
import com.google.inject.Injector;
public class XmlGuiceBootstrapper {
public static void main(String` arguments) {
= Guice.createInjector(new XmlGuiceModule());
Injector injector = injector.getInstance(DefaultGreeter.class);
Greeter greeter System.out.println(greeter.getGreeting());
}
}
The Spring JavaConfig Configuration
simply leverages the
@ImportXml
annotation to bind the beans in Spring
configuration.
package com.earldouglas.guicespringjc.spring;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.config.java.annotation.ImportXml;
@Configuration
@ImportXml(locations = "classpath:com/earldouglas/guicespringjc/spring/config.xml")
public class XmlSpringConfiguration {
}
XmlSpringConfiguration
is bootstrapped exactly as was
SimpleSpringConfiguration
.
package com.earldouglas.guicespringjc.spring;
import org.springframework.config.java.context.JavaConfigApplicationContext;
import com.earldouglas.guicespringjc.Greeter;
public class XmlSpringBootstrapper {
public static void main(String` arguments) {
= new JavaConfigApplicationContext(XmlSpringConfiguration.class);
JavaConfigApplicationContext applicationContext = applicationContext.getBean(Greeter.class);
Greeter greeter System.out.println(greeter.getGreeting());
}
}
Guice certainly plays well with Spring, but not quite as well as Spring itself.