Pobierz

Transkrypt

Pobierz
Kontenery IoC dla Java
Guice 3.0
20 maja 2014
Kamil Piętak
[email protected]
Agenda
 Przegląd implementacji kontenerów IoC
 Guice 3.0




Wprowadzenie – pierwsze kroki
Definicja zależności
Rodzaje wiązań (ang. bindings)
Kontrola instancjonowania
Copyright © 2014 IISG
Implementacje kontenerów IoC
Źródło: http://picocontainer.org/inversion-of-control-history.html
Copyright © 2014 IISG
Implementacje kontenerów IoC
Spring
 Wszystkie sposoby wstrzykiwania – zalecane
wstrzykiwanie przez metody typu „set” – jednostką
składania są bean’y
 Konfiguracja kontenera za pomocą pliku XML (w
nowszych wersja możliwe jest wykorzystanie adnotacji)
 Zasięgi prototype i singleton (jedna instancja w obrębie
kontenera, a nie całego systemu!); dedykowane zasięgi
dla aplikacji webowych (request, session, global session)
 Aktualnie – rozbudowany framework wspomagający
tworzenie aplikacji
Copyright © 2014 IISG
Implementacje kontenerów IoC
 PicoContainer
 Wszystkie sposoby wstrzykiwania – zalecane
wstrzykiwanie przez konstruktor
 Konfiguracja kontenera za pomocą API; projekt
PicoContainer Script – odczyt konfiguracji z
zewnętrznych formatów
 Zasięgi prototype, cached (odpowiednik zasięgu
singleton), thread-cached; dedykowane zasięgi dla
aplikacji webowych
 Prace nad wersją 3.0, projekt wygląda na nieaktywny
Copyright © 2014 IISG
Implementacje kontenerów IoC
 Guice
 Wszystkie sposoby wstrzykiwania – w każdym przypadku
wymagane adnotacje
 Konfiguracja kontenera za pomocą fluent API – moduły
konfiguracyjne
 Zasięgi prototype, singleton; dedykowane zasięgi dla
aplikacji webowych; możliwość tworzenia własnych
zasięgów
 Nacisk na sprawdzanie zgodności typów
 Prace nad wersją 4.0, zgodną z Java 8.
Copyright © 2014 IISG
Tendencja rozwoju bibliotek IoC
 Kontener IoC jako element większych środowisk
wspomagających tworzenie aplikacji
 Spring Framework
 Eclipse RCP 4.x
Copyright © 2014 IISG
Guice 3.0
Pierwsze kroki
 Przykład
Copyright © 2014 IISG
Manulane składanie zależności
class Starter {
public Starter() {
IPM pm = new DatabasePersistenceManager();
this.invCatalogue = new InvoicesCatalogue(pm);
}
}
Copyright © 2014 IISG
Metoda fabryczna
class Starter {
public Starter() {
this.invCatalogue = Factory.getInvCatalogue();
}
}
class Factory {
public InvoicesCatalogue getInvCatalogue() {
return new InvoicesCatalogue(new DatabasePM());
}
}
Copyright © 2014 IISG
Odwrócenie sterowania
class Starter {
public Starter() {
this.invCatalogue = IoC.getInstance(
InvoicesCatalogue.class);
}
}
class InvoicesCatalogue {
@Inject
public InvoicesCatalogue(IPersistenceManager pm) {
this.pm = pm;
}
}
Copyright © 2014 IISG
Pierwsze kroki
 Kontener IoC (Injector) tworzy obiekt InvoicesCatalogue
wraz z wymaganymi zależnościami
InvoicesCatalogue
DatabasePersistenceManager
Konfiguracja
Konfiguracja
Injector
Działający katalog z
wypełnioną listą faktur
Copyright © 2014 IISG
Pierwsze kroki
1) Definicja zależności
public class InvoicesCatalogue {
private IPersistenceManager manager;
Adnotacja konstruktora
wskazujaca ze konstruktor
moze byc wykorzystany
przez kontener IoC do
tworzenia obiektu
@Inject
public InvoicesCatalogue(IPersistenceManager manager) {
this.manager = manager;
...
}
...
}
Copyright © 2014 IISG
Pierwsze kroki
2) Konfiguracja kontenera IoC – Moduł (ang. module)
 Opisuje sposób składania aplikacji
 Wskazuje typy lub obiekty, które mają być
Rozszerzamy
„wstrzykniętę”
abstrakcyjny moduł
public class InvoicesModule extends AbstractModule {
Implementujemy
@Override
metodę configure
protected void configure() {
definiując wiązania
bind(IPersistenceManager.class)
.to(DatabasePersistenceManager.class);
...
}
}
Copyright © 2014 IISG
Pierwsze kroki
3) Wiązania (ang. bindings)
 Skojarzenie interfejsu z konkretną implementacją
 API
 powiązanie interfejsu IPersistenceManager
z implementację bazodanową
bind(IPersistenceManager.class).to(DatabasePersistenceManager.class);
Copyright © 2014 IISG
Pierwsze kroki
4) Tworzenie kontenera IoC
Injector injector = Guice.createInjector(new InvoicesModule());
5) Pobranie zainicjalizowanego obiektu z kontenera
InvoicesCatalogue invoices =
injector.getInstance(InvoicesCatalogue.class);
invoices.addInvoice(...);
Copyright © 2014 IISG
Definicja zależności
 Przez konstruktor
public class InvoicesCatalogue {
private IPersistenceManager manager;
private ILogger logger;
@Inject
public InvoicesCatalogue(IPersistenceManager manager,
ILogger logger) {
this.manager = manager;
this.logger = logger;
}
}
Uwaga: Adnotacja @Inject nie jest wymagana dla bezargumentowych
konstruktorów publicznych.
Copyright © 2014 IISG
Definicja zależności
 Przez metodę
public class InvoicesCatalogue {
private IPersistenceManager manager;
private ILogger logger;
@Inject
public setPM(IPersistenceManager manager) {
this.manager = manager;
}
@Inject
public setLogger(ILogger logger) {
this.logger = logger;
}
Adnotacja @Inject jest
wymagana dla każdej
metody
}
Copyright © 2014 IISG
Definicja zależności
 Przez pole
public class InvoicesCatalogue {
@Inject
private IPersistenceManager manager;
@Inject
private ILogger logger;
}
 Opcjonalne zależności
public class DatabasePersistenceManager {
@Inject(optional=true)
public void setUrl(String url) { ...
Copyright © 2014 IISG
Rodzaje wiązań (bindings)
1) Linked bindings
Copyright © 2014 IISG
Rodzaje wiązań (bindings)
1) Linked bindings
public class InvoicesModule extends AbstractModule {
@Override
protected void configure() {
Skojarzenie intefejsu
bind(ILogger.class).to(FileLogger.class);
ILogger z klasą
FileLogger
bind(IPersistenceManager.class)
.to(DatabasePersistenceManager.class);
bind(DatabasePersistenceManager.class)
.to(MySqlPersistenceManager.class);
}
Linked bindings mogą
być łączone w łańcuchy
}
Copyright © 2014 IISG
Rodzaje wiązań (bindings)
2) Nazwane wiązania (ang. named bindings)
bind(ILogger.class).to(FileLogger.class);
bind(ILogger.class).to(ConsoleLogger.class);
Błąd: Kontener nie wie,
której implementacji
użyć!!!
Copyright © 2014 IISG
Rodzaje wiązań (bindings)
2) Nazwane wiązania (ang. named bindings)
W definicji typu dodajemy dodatkowy „klucz-nazwę” dla zależności:
public class InvoicesCatalogue {
@Inject @Named(„Invoices") ILogger logger;
}
Następnie, aby powiązać nazwaną zależność z typem należy wykorzystać metodę
annotatedWith jak pokazano niżej:
bind(ILogger.class).annotatedWith(Names.named(„Invoices"))
.to(ConsoleLogger.class);
bind(ILogger.class).annotatedWith(Names.named(„GUI"))
.to(FileLogger.class);
Copyright © 2014 IISG
Rodzaje wiązań (bindings)
3) Providers
 Zależność do klasy dostarczonej z zewnętrznej biblioteki
np. brak adnotacji @Inject na konstruktorze,
metodach typu „set”, etc.
 Dodatkowa inicjalizacja
PersistenceManager = manager = new DatabasePersistenceManager();
manager.setJdbcUrl(”jdbc:mysql://localhost/db”);
manager.setTheadPoolSize(30);
Copyright © 2014 IISG
Rodzaje wiązań (bindings)
3) Providers
 Metoda provides w module
public class ExampleModule extends AbstractModule {
@Provides
IPersistenceManager providePersistenceManager() {
DatabasePersistenceManager manager = new
DatabasePersistenceManager();
manager.setJdbcUrl(”jdbc:mysql://localhost/db”);
manager.setTheadPoolSize(30);
return manager;
}
}
 Klasa rozszerzjąca interfejs IProvider<T>
Copyright © 2014 IISG
Rodzaje wiązań (bindings)
4) Just-In-Time bindings
 Domyślne implementacje typów
@ImplementedBy(DatabasePersistenceManager.class)
public interface IPersistenceManager {
}
 Powyższy kod jest równoznaczny z:
bind(IPersistenceManager.class).to(DatabasePersistenceManager.class)
 Domyślne wiązanie może być nadpisane w metodzie
configure (np. w przypadku konfiguracji testowej)
Copyright © 2014 IISG
Kontrola instancjonowania
Wybrane zasięgi:
1) Domyślnie zasięg prototype
2) Zasięg singleton
 Adnotacja @Singleton na implementacji
@Singleton
public class DatabasePersistenceManager implements
IPersistenceManager
 Podczas definicji wiązania
bind(IPersistenceManager.class)
.to(DatabasePersistenceManager.class).in(Singleton.class);
Uwaga: klasy o zasięgu singleton powinny być thread-safe!
Copyright © 2014 IISG
Bibliografia
 Dependency Injection, Design
patterns using Spring and Guice,
Dhanji R. Prasanna
 Google Guice Documentation,
http://code.google.com/p/google-guice/wiki/GettingStarted
Copyright © 2014 IISG

Podobne dokumenty