jug guice presentation
Post on 11-Nov-2014
1.411 Views
Preview:
DESCRIPTION
TRANSCRIPT
Google Guice
Kirill AfanasjevSoftware Architect
jug.lvRiga, Latvia
Overview
Dependency Injection Why Guice Getting Guice Using Guice Advanced Guice
Code without DI
public void sendButtonClicked() {
String text = messageArea.getText();
Validator validator = new MailValidator();
validator.validate(text);
MailSender sender = new MailSender();
sender.send(text);
}
Using factories
public void sendButtonClicked() {
String text = messageArea.getText();
Validator validator = ValidatorFactory.get();
validator.validate(text);
MailSender sender = SenderFactory.get();
sender.send(text);
}
Testable now
public void testSendButton() {
MockSender mockSender = new MockSender();
SenderFactory.setInstance(mockSender);
MailForm form = new MailForm();
form.getMessageArea().setText("Some text");
form.sendButtonClicked();
assertEquals("Some text", mockSender.getSentText());
SenderFactory.clearInstance();
}
Well, not really
public void testSendButton() {
MockSender mockSender = new MockSender();
SenderFactory.setInstance(mockSender);
try {
MailForm form = new MailForm();
form.getMessageArea().setText("Some text");
form.sendButtonClicked();
assertEquals("Some text", mockSender.getSentText());
} finally {
SenderFactory.clearInstance();
}
}
Dependency injection
private Validator validator;
private MailSender mailSender;
public MailForm(Validator validator, MailSender mailSender) {
this.validator = validator;
this.mailSender = mailSender;
}
public void sendButtonClicked() {
…..
Testing now
public void testSendButton() {
MockSender mockSender = new MockSender();
Validator validator = new Validator();
MailForm form = new MailForm(validator, mockSender);
form.getMessageArea().setText("Some text");
form.sendButtonClicked();
assertEquals("Some text", mockSender.getSentText());
}
Why DI frameworks
Avoid boilerplate code AOP Integrate your DI with http session/request,
data access APIs, e.t.c Separate dependencies configuration from
code Makes life easier
What is Guice
Open source dependency injection framework License : Apache License 2.0 Developer : Google
Why Guice
Java API for configuration Easier to use Line numbers in error messages Less overhead Less features, too DI in GWT client-side code (using GIN)
Getting Guice
http://code.google.com/p/google-guice/ http://mvnrepository.com/ Small – 865 KB Version without AOP, suitable for Android –
470KB Lacks fast reflection and line numbers in errors
Dependency injection with Guice
private Validator validator;
private MailSender mailSender;
@Inject
public MailForm(Validator validator, MailSender mailSender) {
this.validator = validator;
this.mailSender = mailSender;
}
Creating instance of MailForm
Injector injector =
Guice.createInjector(new YourAppModule());
MailForm mailForm = injector.getInstance(MailForm.class);
Bindings
public class YourAppModule extends AbstractModule {
protected void configure() {
bind(MailService.class).to(MailServiceImpl.class);
bind(Validator.class).to(ValidatorImpl.class);
}
}
Providers
public class YourAppModule extends AbstractModule {
protected void configure() {
bind(Validator.class).to(ValidatorImpl.class);
}
@Provides
MailService getMailService() {
MailService service = new MailService();
return service;
}
….
Injecting fields
@Inject
private Validator validator;
@Inject
private MailSender mailSender;
public MailForm() {
}
Injecting with setter methods
private Validator validator;
public MailForm() {
}
@Inject
public void setValidator(Validator validator) {
this.validator = validator;
}
Optional injection
Inject(optional=true) Ignores values for which no bindings are
avalaible Possible with setter methods only
Bind instance
protected void configure() {
bind(Integer.class).annotatedWith(ThreadCount.class).toInstance(4);
}
..
@ThreadCount
int threadCount;
IDE autocomplete, find usages e.t.c
Two implementations
protected void configure() {
bind(Validator.class).to(ValidatorImpl.class);
bind(Validator.class).to(StrictValidatorImpl.class);
}
Two implementations
Exception in thread "main" com.google.inject.CreationException:
Guice configuration errors:
1) Error at lv.jug.MailService.configure(YourAppModule.java:12):
A binding to lv.jug.MailService was already configured at
lv.jug.YourAppModule.configure(YourAppModule.java:11)
Two implementations
protected void configure() {
bind(Validator.class).to(ValidatorImpl.class);
bind(Validator.class)
.annotatedWith(Strict.class)
.to(StrictValidatorImpl.class);
}
….
@Inject
public MailForm(@Strict Validator validator) {
this.validator = validator;
}
Binding annotation
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@BindingAnnotation
public @interface Strict {}
Implicit binding
@Inject
public MailForm(
@ImplementedBy(StrictValidator.class) Validator Validator validator,
MailSender mailSender) {
this.validator = validator;
this.mailSender = mailSender;
}
Static injection
protected void configure() {
bind(Validator.class).to(ValidatorImpl.class);
requestStaticInjection(OurClass.class);
}
…
…
@Inject static Validator validator;
Scoping
protected void configure() {
bind(Validator.class).to(ValidatorImpl.class)
.in(Scopes.SINGLETON);bind(MailService.class).to(MailServiceImpl.class)
.asEagerSingleton();}
Multibindings
Multibinder<Plugin> pluginBinder = Multibinder.newSetBinder(binder(), Plugin.class);
pluginBinder.addBinding().to(SomePluginImpl.class);
pluginBinder.addBinding().to(AnotherPluginImpl.class);
….
@Inject Set<Plugin> plugins
Grapher
Describe the object graph in detail Show bindings and dependencies from several
classes in a complex application in a unified diagram
Generates .dot file
Advanced Guice
AOP Warp Google Gin Spring integration Using guice with Servlets
Why AOP
Transaction handling Logging Security Exception handling e.t.c
AOP
void bindInterceptor(
Match <? super Class<?>> classMatcher,
Matcher<? super Method> methodMatcher,
MethodInterceptor... interceptors)
public interface MethodInterceptor extends Interceptor {
Object invoke (MethodInvocation invocation) throws Throwable
}
AOP
You can not match on private and final methods due to technical limitations in Java
Only works for objects Guice creates
Warp
http://www.wideplay.com/ Eco-system for Google Guice Thin lightweight modules for Guice applications Persistence Transactions Servlets
Warp-persist
Supports : Hibernate/JPA/Db4Objects Inject DAOs & Repositories Flexible units-of-work Declarative transaction management
( @Transactional ) Your own AOP for transactions management @Finder(query="from Person")
Google Gin
Automatic dependency injection for GWT client-side code
Code generation Little-to-no runtime overhead, compared to
manual DI Uses Guice binding language http://code.google.com/p/google-gin/
Spring integration
http://code.google.com/p/guice-spring/ @Named(”mySpringBean”)
JSR-330
javax.inject @Inject @Named @Qualifier @Scope @Singleton e.t.c Supported by Guice, Spring, EJB
Using Guice with Servlets
@RequestScoped @SessionScoped ServletModule serve(”/admin”).with(AdminPanelServlet.class) serve("*.html", "/my/*").with(MyServlet.class) filter(”/*”).through(MyFilter.class) @Inject @RequestParameters Map<String,
String[]> params;
Thank you
Questions ?
top related