<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog Espeo Software &#187; gin</title>
	<atom:link href="http://blog.espeo.pl/tag/gin/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.espeo.pl</link>
	<description>O technologii i biznesie naszym zdaniem</description>
	<lastBuildDate>Mon, 05 Jul 2010 12:16:55 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Google GIN, czyli dependency injection w GWT</title>
		<link>http://blog.espeo.pl/2009/09/04/google-gin-czyli-dependency-injection-w-gwt/</link>
		<comments>http://blog.espeo.pl/2009/09/04/google-gin-czyli-dependency-injection-w-gwt/#comments</comments>
		<pubDate>Fri, 04 Sep 2009 15:05:48 +0000</pubDate>
		<dc:creator>Michał Kalinowski</dc:creator>
				<category><![CDATA[technologia]]></category>
		<category><![CDATA[gin]]></category>
		<category><![CDATA[guice]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://blog.espeo.pl/?p=160</guid>
		<description><![CDATA[Wstęp
Google GIN (GWT INjection) to stosunkowo młody projekt Google, wprowadzający do Google Web Toolkit możliwość wstrzykiwania zależności (ang. dependency injection). Oparty jest na Google Guice (o którym pisałem kilka tygodni temu) i zapewnia pewien podzbiór funkcjonalności tej biblioteki.  Po co więc GIN? Potrzeba wynika wprost ze specyfiki aplikacji tworzonych w GWT, która uniemożliwia zastosowanie &#8220;typowego&#8221; [...]]]></description>
			<content:encoded><![CDATA[<h2>Wstęp</h2>
<p><a href="http://code.google.com/p/google-gin/" target="_blank">Google GIN (GWT INjection)</a> to stosunkowo młody projekt Google, wprowadzający do <a href="http://code.google.com/webtoolkit/" target="_blank">Google Web Toolkit</a> możliwość wstrzykiwania zależności (ang. <em>dependency injection</em>). Oparty jest na <a href="http://code.google.com/p/google-guice/" target="_blank">Google Guice</a> (o którym <a href="http://blog.espeo.pl/2009/08/18/google-guice-dependency-injection-framework/" target="_blank">pisałem kilka tygodni temu</a>) i zapewnia pewien podzbiór funkcjonalności tej biblioteki.  Po co więc GIN? Potrzeba wynika wprost ze specyfiki aplikacji tworzonych w GWT, która uniemożliwia zastosowanie &#8220;typowego&#8221; frameworka do wstrzykiwania zależności. Rozwinę ten temat za chwilę.</p>
<p>Póki co, nie ma możliwości pobrania skompilowanej biblioteki ze strony projektu (tak jak pisałem, jest to jeszcze wczesna faza rozwoju), więc pozostaje <em>check out</em> z publicznego repozytorium i własnoręczna kompilacja:</p>
<pre>
<pre class="brush: bash;">
svn checkout http://google-gin.googlecode.com/svn/trunk/ google-gin-read-only
cd google-gin-read-only
ant dist
</pre>
</pre>
<p>Zbudowanego JARa (<strong>./out/dist/gin.jar</strong>) oczywiście należy dołączyć do swojego projektu.</p>
<h2>Zaczynamy!</h2>
<p>Mamy już dostępne klasy GIN, więc można zaczynać. W regularnym Guice, po skonfigurowaniu zależności w klasie modułu i utworzeniu <strong>Injector</strong>a, obiekty pobiera się mniej więcej tak:</p>
<pre>
<pre class="brush: java;">
RegistrationService registrationService = injector.getInstance(RegistrationService.class);
</pre>
</pre>
<p>W GWT jednak powyższy kod nie zadziała. Żeby być ścisłym: nie zadziała w komponentach po stronie klienta (ang. <em>client-side</em>). Jak wiadomo, aplikacja GWT dzieli się na stronę klienta i stronę serwera. Po stronie serwera nie ma żadnego problemu ze wstrzykiwaniem zależności. Obiekty są instancjonowane w rzeczywistym JRE (najczęściej w kontenerze serwletów) i żyją &#8220;normalnym&#8221; Javowym życiem. Można używać Guice, Spring albo dowolnego innego rozwiązania do wstrzykiwania zależności i będzie działać. Po stronie klienta wygląda to jednak zupełnie inaczej, ponieważ kod Java jest kompilowany do JavaScript, więc JRE nie istnieje (jest jedynie w niewielkim zakresie emulowane przez bibliotekę GWT). Standardowe użycie Guice nie zadziała więc z dwóch powodów:</p>
<ul>
<li>Na poziomie JavaScript nie istnieją klasy.</li>
<li>Guice (podobnie jak większość tego typu rozwiązań) często korzysta z mechanizmu <em>reflection</em> Javy, który nie jest w ogóle emulowany w GWT.</li>
</ul>
<p>GIN stosuje więc inny sposób na zapewnienie wstrzykiwania zależności. Na początek należy zaimportować moduł GIN we własnym module GWT.</p>
<pre>
<pre class="brush: xml;">
&lt;module&gt;
  ...
  &lt;inherits name=&quot;com.google.gwt.inject.Inject&quot; /&gt;
  ...
&lt;/module&gt;
</pre>
</pre>
<p>Teraz funkcjonalność oferowana przez GIN jest dostępna w obrębie strony klienta aplikacji GWT. Dochodzimy jednak ponownie do momentu, gdy &#8220;jakoś&#8221; trzeba w końcu te zależności pobrać. W GIN używa się do tego specjalnej wersji <strong>Injector</strong>a &#8212; <strong>Ginjector</strong>a (który jednak de facto nie jest związany relacją dziedziczenia z tym pierwszym).</p>
<pre>
<pre class="brush: java;">
public interface ApplicationGinjector extends Ginjector {
    ApplicationPresenter getApplicationPresenter();
}
</pre>
</pre>
<p><strong>Ginjector</strong> powinien oferować tylko komponenty potrzebne na etapie inicjalizacji aplikacji. Przy ich pobieraniu zostaną zainicjowane ich zależności, a więc również zależności tych zależności itd. W ten sposób zostanie zbudowany cały graf obiektów, a zależności automatycznie powstrzykiwane. W tym przypadku, komponentem potrzebnym na samym początku działania aplikacji jest <strong>ApplicationPresenter</strong>, który wyświetla ekran startowy. Zależności definiuje się dokładnie tak jak w Guice, czyli za pomocą adnotacji <strong>@Inject</strong>.</p>
<p>Jak wiadomo, <strong>Injector</strong> potrzebuje również modułu, w którym zawarte są informacje na temat komponentów.</p>
<pre>
<pre class="brush: java;">
public class ApplicationClientModule extends AbstractGinModule {
    @Override
    protected void configure() {
        bind(ApplicationPresenter.class);
        // other bindings...
    }
}
</pre>
</pre>
<p>Jak widać, moduł po stronie klienta w GWT dziedziczy z <strong>AbstractGinModule</strong>. Poza tym wszystko wygląda dokładnie jak w Guice. Istotnym niuansem związanym z modułami GIN jest fakt, że w przypadku nie odnalezienia powiązania dla klasy, automatycznie wywoływana jest dla niej metoda <strong>GWT.create()</strong>, przez co niektóre rzeczy (np. asynchroniczne interfejsy usług) będą działać nawet bez odpowiedniej deklaracji w klasie modułu.</p>
<p>Zdefiniowany moduł należy jeszcze skojarzyć z właściwym interfejsem <strong>Ginjector</strong> za pomocą adnotacji <strong>@GinModules</strong>.</p>
<pre>
<pre class="brush: java;">
@GinModules(ApplicationClientModule.class)
public interface ApplicationGinjector extends Ginjector {
    ApplicationPresenter getApplicationPresenter();
}
</pre>
</pre>
<p>W ten sposób, <strong>Ginjector</strong> jest w stanie skonfigurować całą aplikację na podstawie danych zawartych w określonym module. Aby to zrobić, należy go utworzyć za pomocą wywołania <strong>GWT.create()</strong> oraz pobrać początkowe obiekty.</p>
<pre>
<pre class="brush: java;">
public final class Application implements EntryPoint {
    public void onModuleLoad() {
        ApplicationGinjector injector = GWT.create(ApplicationGinjector.class);
        ApplicationPresenter applicationPresenter = injector.getApplicationPresenter();
        applicationPresenter.go(RootPanel.get());
    }
}
</pre>
</pre>
<p>W ten sposób, cała procedura wstrzykiwania zależności ma miejsce już w czasie kompilacji. Użycie GIN nie jest więc związane z żadnym dodatkowym narzutem przetwarzania. (Wyszłoby na to samo, gdybyśmy konfigurowali komponenty ręcznie.)</p>
<h2>Prawie jak Guice</h2>
<p>Z użyciem GIN jest związanych kilka niuansów, o czym wspomniałem już na samym początku. GIN to nie jest mimo wszystko to samo co Guice, tylko dla GWT. Najbardziej istotne różnice w stosunku do Guice to:</p>
<ul>
<li>Zamiast typów <strong>Module</strong> i <strong>AbstractModule</strong> są <strong>GinModule</strong> i <strong>AbstractGinModule</strong>.</li>
<li>Zamiast typu <strong>Injector</strong> jest <strong>Ginjector</strong> z adnotacją <strong>@GinModules</strong>.</li>
<li>Niemożliwe jest użycie powiązania <strong>toInstance()</strong> i prawdopodobnie nigdy nie będzie możliwe (ze względu na to, że GIN działa w czasie kompilacji, a nie wykonania).</li>
<li>Na chwilę obecną nie jest możliwe definiowanie własnych zasięgów.</li>
<li>Nie ma adnotacji <strong>@ImplementedBy</strong> oraz <strong>@ProvidedBy</strong>.</li>
<li>Brak obsługi zależności cyklicznych.</li>
<li>Brak wsparcia dla AOP.</li>
</ul>
<p>Warto jeszcze dodać, że istnieje sposób na współpracę z regularnym Guice za pomocą klasy <strong>GinModuleAdapter</strong>, dzięki której <strong>GinModule</strong> staje się dostępny jako zwykły <strong>Module</strong>. Można więc rozważyć utworzenie wspólnej części zależności w postaci <strong>GinModule</strong>. Ponadto, zrozumienie jak działa strona klienta w GWT na pewno pomoże uniknąć wielu potencjalnych problemów z GIN.</p>
<h2>Podsumowanie</h2>
<p>Jak widać, w GWT również można wygodnie wstrzykiwać zależności i to korzystając z bardzo przyjaznego API znanego z Guice. Mimo, że biblioteka ta jest jeszcze nieco niedojrzała i nie doczekała się nawet wersji 1.0, moim zdaniem warto się nią zainteresować i zastosować we własnych projektach w Google Web Toolkit. Używając jej przez ostatnie kilka miesięcy nie napotkałem żadnych problemów (w szczególności ze stabilnością), a znacząco ułatwiłem sobie pracę, rezygnując z ręcznego wstrzykiwania zależności. Myślę, że Google jeszcze nie raz zaskoczy nas różnymi ciekawymi dodatkami do GWT. Póki co, zapraszam na <a href="http://code.google.com/p/google-gin/" target="_blank">stronę domową projektu</a> oraz zachęcam do własnych eksperymentów z Google GIN.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.espeo.pl/2009/09/04/google-gin-czyli-dependency-injection-w-gwt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
