jug guice presentation

Post on 11-Nov-2014

1.411 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

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