Google Guice - Krótki przewodnik

Guice to oparty na Javie framework iniekcji zależności typu open source. Jest cichy, lekki i jest aktywnie rozwijany / zarządzany przez Google.

Dependency Injection

Każda aplikacja oparta na języku Java ma kilka obiektów, które współpracują ze sobą, prezentując to, co użytkownik końcowy widzi jako działającą aplikację. Pisząc złożoną aplikację Java, klasy aplikacji powinny być jak najbardziej niezależne od innych klas Java, aby zwiększyć możliwość ponownego użycia tych klas i testowania ich niezależnie od innych klas podczas testów jednostkowych. Dependency Injection (lub czasami nazywany okablowaniem) pomaga w sklejaniu tych klas ze sobą, a jednocześnie utrzymaniu ich niezależności.

Rozważ, że masz aplikację, która ma komponent edytora tekstu i chcesz zapewnić sprawdzanie pisowni. Twój standardowy kod wyglądałby mniej więcej tak -

public class TextEditor {
   private SpellChecker spellChecker;
   
   public TextEditor() {
      spellChecker = new SpellChecker();
   }
}

To, co tutaj zrobiliśmy, to stworzenie zależności między TextEditor a SpellChecker. W scenariuszu odwrócenia kontroli zamiast tego zrobilibyśmy coś takiego -

public class TextEditor {
   private SpellChecker spellChecker;
   
   @Inject
   public TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }
}

Tutaj TextEditor nie powinien przejmować się implementacją sprawdzania pisowni. SpellChecker zostanie zaimplementowany niezależnie i zostanie dostarczony do TextEditor w czasie tworzenia instancji TextEditor.

Dependency Injection using Guice (Binding)

Dependency Injection jest kontrolowany przez Guice Bindings. Guice używa powiązań do mapowania typów obiektów na ich rzeczywiste implementacje. Te powiązania są zdefiniowane jako moduł. Moduł to zbiór powiązań, jak pokazano poniżej:

public class TextEditorModule extends AbstractModule {
   @Override 
   protected void configure() {
      /*
      * Bind SpellChecker binding to WinWordSpellChecker implementation 
      * whenever spellChecker dependency is used.
      */
      bind(SpellChecker.class).to(WinWordSpellChecker.class);
   }
}

Moduł jest podstawowym blokiem konstrukcyjnym wtryskiwacza, który jest konstruktorem grafów obiektów Guice. Najpierw należy stworzyć wtryskiwacz, a następnie możemy użyć wtryskiwacza, aby uzyskać obiekty.

public static void main(String[] args) {
   /*
   * Guice.createInjector() takes Modules, and returns a new Injector
   * instance. This method is to be called once during application startup.
   */
   Injector injector = Guice.createInjector(new TextEditorModule());
   /*
   * Build object using injector
   */
   TextEditor textEditor = injector.getInstance(TextEditor.class);   
}

W powyższym przykładzie graf obiektu klasy TextEditor jest konstruowany przez Guice i ten wykres zawiera obiekt TextEditor i jego zależność jako obiekt WinWordSpellChecker.

Konfiguracja środowiska lokalnego

Jeśli nadal chcesz skonfigurować środowisko pod kątem języka programowania Java, w tej sekcji omówiono sposób pobierania i konfigurowania środowiska Java na komputerze. Wykonaj poniższe czynności, aby skonfigurować środowisko.

Java SE jest dostępna bezpłatnie pod linkiem Pobierz Javę . Więc pobierasz wersję opartą na systemie operacyjnym.

Postępuj zgodnie z instrukcjami, aby pobrać Javę i uruchomić .exeaby zainstalować Javę na swoim komputerze. Po zainstalowaniu Javy na swoim komputerze należałoby ustawić zmienne środowiskowe, aby wskazywały na prawidłowe katalogi instalacyjne -

Konfigurowanie ścieżki dla Windows 2000 / XP

Zakładamy, że zainstalowałeś Javę w katalogu c: \ Program Files \ java \ jdk -

  • Kliknij prawym przyciskiem myszy „Mój komputer” i wybierz „Właściwości”.

  • Kliknij przycisk „Zmienne środowiskowe” na karcie „Zaawansowane”.

  • Teraz zmień zmienną „Path”, tak aby zawierała również ścieżkę do pliku wykonywalnego Java. Na przykład, jeśli ścieżka jest obecnie ustawiona na „C: \ WINDOWS \ SYSTEM32”, ​​zmień ścieżkę na „C: \ WINDOWS \ SYSTEM32; c: \ Program Files \ java \ jdk \ bin”.

Konfigurowanie ścieżki dla Windows 95/98 / ME

Zakładamy, że zainstalowałeś Javę w katalogu c: \ Program Files \ java \ jdk -

  • Edytuj plik „C: \ autoexec.bat” i dodaj na końcu następujący wiersz - „SET PATH =% PATH%; C: \ Program Files \ java \ jdk \ bin”

Konfigurowanie ścieżki dla systemów Linux, UNIX, Solaris, FreeBSD

Zmienna środowiskowa PATH powinna być ustawiona tak, aby wskazywała, gdzie zostały zainstalowane pliki binarne Java. Zajrzyj do dokumentacji powłoki, jeśli masz z tym problem.

Na przykład, jeśli używasz bash jako powłoki, to dodasz następujący wiersz na końcu swojego '.bashrc: export PATH = / path / to / java: $ PATH'

Popularne edytory Java

Do pisania programów w języku Java potrzebny jest edytor tekstu. Na rynku dostępnych jest wiele wyrafinowanych IDE. Ale na razie możesz rozważyć jedną z następujących -

  • Notepad - Na komputerze z systemem Windows możesz użyć dowolnego prostego edytora tekstu, takiego jak Notatnik (zalecany w tym samouczku), TextPad.

  • Netbeans - Jest to środowisko Java IDE o otwartym kodzie źródłowym i bezpłatne, które można pobrać z witryny https://www.netbeans.org/index.html.

  • Eclipse - Jest to również środowisko Java IDE opracowane przez społeczność eclipse open source i można je pobrać z witryny https://www.eclipse.org/.

Środowisko Google Guice

Pobierz najnowszą wersję Google Guice i powiązane pliki jar.

  • Google Guice 4.0

  • AOP Alliance 1.0

  • Guawa 16.0.1

  • javax.inject 1.0

W momencie pisania tego samouczka skopiowaliśmy je do folderu C: \> Google.

OS Nazwa archiwum
Windows guice-4.1.0.jar; aopalliance-1.0.jar; guava-16.0.1.jar; javax.inject-1.jar
Linux guice-4.1.0.jar; aopalliance-1.0.jar; guava-16.0.1.jar; javax.inject-1.jar
Prochowiec guice-4.1.0.jar; aopalliance-1.0.jar; guava-16.0.1.jar; javax.inject-1.jar

Ustaw zmienną CLASSPATH

Ustaw CLASSPATHzmienna środowiskowa wskazująca lokalizację jar Guice. Zakładając, że przechowujesz Guice i powiązane pliki jar w folderze Google w różnych systemach operacyjnych w następujący sposób.

OS Wynik
Windows Ustaw zmienną środowiskową CLASSPATH na% CLASSPATH%; C: \ Google \ guice-4.1.0.jar; C: \ Google \ aopalliance-1.0.jar; C: \ Google \ guava-16.0.1.jar; C: \ Google \ javax.inject-1.jar;.;
Linux export CLASSPATH = $ CLASSPATH: Google / guice-4.1.0.jar: Google / aopalliance-1.0.jar: Google / guava-16.0.1.jar: Google / javax.inject-1.jar :.
Prochowiec export CLASSPATH = $ CLASSPATH: Google / guice-4.1.0.jar: Google / aopalliance-1.0.jar: Google / guava-16.0.1.jar: Google / javax.inject-1.jar :.

Utwórzmy przykładową aplikację opartą na konsoli, w której krok po kroku zademonstrujemy iniekcję zależności przy użyciu mechanizmu Guice binding.

Krok 1: Utwórz interfejs

//spell checker interface
interface SpellChecker {
   public void checkSpelling();
}

Krok 2: Utwórz implementację

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
   @Override
   public void checkSpelling() {
      System.out.println("Inside checkSpelling." );
   } 
}

Krok 3: Utwórz moduł powiązań

//Binding Module
class TextEditorModule extends AbstractModule {
   @Override
   protected void configure() {
      bind(SpellChecker.class).to(SpellCheckerImpl.class);
   } 
}

Krok 4: Utwórz klasę z zależnościami

class TextEditor {
   private SpellChecker spellChecker;
   @Inject
   public TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }
   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   }
}

Krok 5: Utwórz wtryskiwacz

Injector injector = Guice.createInjector(new TextEditorModule());

Krok 6: Pobierz obiekt z spełnioną zależnością.

TextEditor editor = injector.getInstance(TextEditor.class);

Krok 7: Użyj obiektu.

editor.makeSpellCheck();

Kompletny przykład

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck(); 
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   public TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   }
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      bind(SpellChecker.class).to(SpellCheckerImpl.class);
   } 
}

//spell checker interface
interface SpellChecker {
   public void checkSpelling();
}


//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Override
   public void checkSpelling() {
      System.out.println("Inside checkSpelling." );
   } 
}

Wynik

Skompiluj i uruchom plik, zobaczysz następujące dane wyjściowe.

Inside checkSpelling.

W połączonych powiązaniach Guice mapuje typ na jego implementację. W poniższym przykładzie zmapowaliśmy interfejs SpellChecker z jego implementacją SpellCheckerImpl.

bind(SpellChecker.class).to(SpellCheckerImpl.class);

Możemy również zmapować konkretną klasę do jej podklasy. Zobacz poniższy przykład:

bind(SpellCheckerImpl.class).to(WinWordSpellCheckerImpl.class);

Tutaj związaliśmy wiązania. Zobaczmy wynik w pełnym przykładzie.

Kompletny przykład

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck(); 
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   public TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   }
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      bind(SpellChecker.class).to(SpellCheckerImpl.class);
      bind(SpellCheckerImpl.class).to(WinWordSpellCheckerImpl.class);
   } 
}

//spell checker interface
interface SpellChecker {
   public void checkSpelling();
}


//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Override
   public void checkSpelling() {
      System.out.println("Inside checkSpelling." );
   } 
}

//subclass of SpellCheckerImpl
class WinWordSpellCheckerImpl extends SpellCheckerImpl{
   @Override
   public void checkSpelling() {
      System.out.println("Inside WinWordSpellCheckerImpl.checkSpelling." );
   } 
}

Wynik

Skompiluj i uruchom plik, zobaczysz następujące dane wyjściowe.

Inside WinWordSpellCheckerImpl.checkSpelling.

Ponieważ możemy powiązać typ z jego implementacją. W przypadku, gdy chcemy zmapować typ z wieloma implikacjami, możemy również utworzyć niestandardową adnotację. Zobacz poniższy przykład, aby zrozumieć koncepcję.

Utwórz wiążącą adnotację

@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
@interface WinWord {}
  • @BindingAnnotation - Zaznacza adnotację jako wiążącą adnotację.

  • @Target - Oznaczanie stosowalności adnotacji.

  • @Retention - Oznaczenia dostępności adnotacji jako środowiska uruchomieniowego.

Mapowanie przy użyciu adnotacji wiązania

bind(SpellChecker.class).annotatedWith(WinWord.class).to(WinWordSpellCheckerImpl.class);

Wstrzyknąć za pomocą adnotacji wiązania

@Inject
public TextEditor(@WinWord SpellChecker spellChecker) {
   this.spellChecker = spellChecker;
}

Kompletny przykład

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import java.lang.annotation.Target;

import com.google.inject.AbstractModule;
import com.google.inject.BindingAnnotation;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;

import java.lang.annotation.Retention;

import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;

@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
@interface WinWord {}

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();     
   } 
}

class TextEditor {
   private SpellChecker spellChecker;   

   @Inject
   public TextEditor(@WinWord SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public void makeSpellCheck(){
      spellChecker.checkSpelling(); 
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      bind(SpellChecker.class).annotatedWith(WinWord.class)
         .to(WinWordSpellCheckerImpl.class);    
   } 
}

//spell checker interface
interface SpellChecker {
   public void checkSpelling();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Override
   public void checkSpelling() {
      System.out.println("Inside checkSpelling." );
   } 
}

//subclass of SpellCheckerImpl
class WinWordSpellCheckerImpl extends SpellCheckerImpl{
   @Override
   public void checkSpelling() {
      System.out.println("Inside WinWordSpellCheckerImpl.checkSpelling." );
   } 
}

Wynik

Skompiluj i uruchom plik, zobaczysz następujące dane wyjściowe.

Inside WinWordSpellCheckerImpl.checkSpelling.

Guice zapewnia również inny sposób mapowania powiązań bez tworzenia niestandardowego opisu. Pozwala to na użycie adnotacji @Named.

Mapowanie przy użyciu nazwanej adnotacji

bind(SpellChecker.class).annotatedWith(Names.named("OpenOffice")).to(OpenOfficeWordSpellCheckerImpl.class);

Wstrzyknij za pomocą adnotacji @Named

@Inject
public TextEditor(@Named("OpenOffice") SpellChecker spellChecker) {
   this.spellChecker = spellChecker;
}

Kompletny przykład

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;
   

   @Inject
   public TextEditor(@Named("OpenOffice") SpellChecker spellChecker) {
      this.spellChecker = spellChecker;      
   }

   public void makeSpellCheck(){
      spellChecker.checkSpelling(); 
   }  
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      bind(SpellChecker.class).annotatedWith(Names.named("OpenOffice"))
         .to(OpenOfficeWordSpellCheckerImpl.class);
   } 
}

//spell checker interface
interface SpellChecker {
   public void checkSpelling();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Override
   public void checkSpelling() {
      System.out.println("Inside checkSpelling." );
   } 
}

//subclass of SpellCheckerImpl
class OpenOfficeWordSpellCheckerImpl extends SpellCheckerImpl{
   @Override
   public void checkSpelling() {
      System.out.println("Inside OpenOfficeWordSpellCheckerImpl.checkSpelling." );
   } 
}

Wynik

Skompiluj i uruchom plik, zobaczysz następujące dane wyjściowe.

Inside OpenOfficeWordSpellCheckerImpl.checkSpelling.

Guice zapewnia sposób tworzenia powiązań z obiektami wartości lub stałymi. Rozważmy przypadek, w którym chcemy skonfigurować adres URL JDBC.

Wstrzyknij za pomocą adnotacji @Named

@Inject
public void connectDatabase(@Named("JBDC") String dbUrl) {
   //...
}

Można to osiągnąć za pomocą metody toInstance ().

bind(String.class).annotatedWith(Names.named("JBDC")).toInstance("jdbc:mysql://localhost:5326/emp");

Kompletny przykład

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeConnection();
   } 
}

class TextEditor {
   private String dbUrl;
   @Inject
   public TextEditor(@Named("JDBC") String dbUrl) {
      this.dbUrl = dbUrl;
   }

   public void makeConnection(){
      System.out.println(dbUrl);
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      bind(String.class)
         .annotatedWith(Names.named("JDBC"))
         .toInstance("jdbc:mysql://localhost:5326/emp");
   } 
}

Wynik

Skompiluj i uruchom plik, zobaczysz następujące dane wyjściowe.

jdbc:mysql://localhost:5326/emp

Guice zapewnia sposób tworzenia powiązań ze złożonymi obiektami przy użyciu metody @provides.

@Provides
public SpellChecker provideSpellChecker(){
   String dbUrl = "jdbc:mysql://localhost:5326/emp";
   String user = "user";
   int timeout = 100;
   SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
   return SpellChecker;
}

Ta metoda jest częścią modułu powiązania i zapewnia złożony obiekt do zmapowania. Zobacz pełny przykład poniżej.

Kompletny przykład

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provides;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;
   @Inject
   public TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }
   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {} 

   @Provides
   public SpellChecker provideSpellChecker(){

      String dbUrl = "jdbc:mysql://localhost:5326/emp";
      String user = "user";
      int timeout = 100;

      SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
      return SpellChecker;
   }
}

//spell checker interface
interface SpellChecker {
public void checkSpelling();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   private String dbUrl;
   private String user;
   private Integer timeout;

   @Inject
   public SpellCheckerImpl(String dbUrl, 
      String user, 
      Integer timeout){
      this.dbUrl = dbUrl;
      this.user = user;
      this.timeout = timeout;
   } 

   @Override
   public void checkSpelling() { 
      System.out.println("Inside checkSpelling." );
      System.out.println(dbUrl);
      System.out.println(user);
      System.out.println(timeout);
   }
}

Wynik

Skompiluj i uruchom plik, zobaczysz następujące dane wyjściowe.

Inside checkSpelling.
jdbc:mysql://localhost:5326/emp
user
100

Ponieważ metoda @provides staje się bardziej złożona, metody te można przenieść do oddzielnych klas za pomocą interfejsu dostawcy.

class SpellCheckerProvider implements Provider<SpellChecker>{
   @Override
   public SpellChecker get() {
      String dbUrl = "jdbc:mysql://localhost:5326/emp";
      String user = "user";
      int timeout = 100;
      SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
      return SpellChecker;
   } 
}

Następnym krokiem jest zmapowanie dostawcy na typ.

bind(SpellChecker.class).toProvider(SpellCheckerProvider.class);

Zobacz pełny przykład poniżej.

Kompletny przykład

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;
   @Inject
   public TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      bind(SpellChecker.class)
         .toProvider(SpellCheckerProvider.class);
   } 
}

//spell checker interface
interface SpellChecker {
   public void checkSpelling();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   private String dbUrl;
   private String user;
   private Integer timeout;

   @Inject
   public SpellCheckerImpl(String dbUrl, 
      String user, 
      Integer timeout){
      this.dbUrl = dbUrl;
      this.user = user;
      this.timeout = timeout;
   } 

   @Override
   public void checkSpelling() { 
      System.out.println("Inside checkSpelling." );
      System.out.println(dbUrl);
      System.out.println(user);
      System.out.println(timeout);
   }
}

class SpellCheckerProvider implements Provider<SpellChecker>{

   @Override
   public SpellChecker get() {
      String dbUrl = "jdbc:mysql://localhost:5326/emp";
      String user = "user";
      int timeout = 100;

      SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
      return SpellChecker;
   }
}

Wynik

Skompiluj i uruchom plik, zobaczysz następujące dane wyjściowe.

Inside checkSpelling.
jdbc:mysql://localhost:5326/emp
user
100

Guice umożliwia tworzenie powiązań z określonym konstruktorem obiektu przy użyciu metody toConstructor ().

@Override
protected void configure() {
   try {
      bind(SpellChecker.class)
         .toConstructor(SpellCheckerImpl.class.getConstructor(String.class));
      } catch (NoSuchMethodException | SecurityException e) {
      System.out.println("Required constructor missing");
   } 
}

Zobacz pełny przykład poniżej.

Kompletny przykład

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;
   @Inject
   public TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      try {
         bind(SpellChecker.class)
            .toConstructor(SpellCheckerImpl.class.getConstructor(String.class));
      } catch (NoSuchMethodException | SecurityException e) {
         System.out.println("Required constructor missing");
      } 
      bind(String.class)
         .annotatedWith(Names.named("JDBC"))
         .toInstance("jdbc:mysql://localhost:5326/emp");
   } 
}

//spell checker interface
interface SpellChecker {
   public void checkSpelling();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   private String dbUrl;

   public SpellCheckerImpl(){}

   public SpellCheckerImpl(@Named("JDBC") String dbUrl){
      this.dbUrl = dbUrl;
   } 

   @Override
   public void checkSpelling() { 
      System.out.println("Inside checkSpelling." );
      System.out.println(dbUrl); 
   }
}

Wynik

Skompiluj i uruchom plik, zobaczysz następujące dane wyjściowe.

Inside checkSpelling.
jdbc:mysql://localhost:5326/emp

Guice zapewnia wbudowane powiązanie dla klasy java.util.logging.Logger . Nazwa Loggera jest automatycznie ustawiana na nazwę klasy, do której jest wstrzykiwany Logger. Zobacz poniższy przykład.

Przykład

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import java.util.logging.Logger;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private Logger logger;

   @Inject
   public TextEditor( Logger logger) {
      this.logger = logger;
   }

   public void makeSpellCheck(){
      logger.info("In TextEditor.makeSpellCheck() method");
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
   } 
}

Wynik

Skompiluj i uruchom plik, zobaczysz następujące dane wyjściowe.

Dec 20, 2017 12:51:05 PM TextEditor makeSpellCheck
INFO: In TextEditor.makeSpellCheck() method

Ponieważ powiązania są zdefiniowane w module powiązań, Guice używa ich, gdy zachodzi potrzeba wstrzyknięcia zależności. W przypadku braku powiązań może podjąć próbę utworzenia powiązań just in time. Powiązania obecne w module powiązań nazywane są jawnymi powiązaniami i mają wyższy priorytet, podczas gdy powiązania just in Time nazywane są niejawnymi powiązaniami. Jeśli oba typy powiązań są obecne, do mapowania są brane pod uwagę jawne powiązania.

Poniżej znajdują się przykłady trzech typów powiązań Just-in-Time.

Typ wiązania Opis
Konstruktory iniekcyjne Konstruktory nieprywatne i bez argumentów kwalifikują się do powiązań just in time. Innym sposobem jest dodanie adnotacji do konstruktora za pomocą adnotacji @Inject.
@ImplementatedBy annotation Adnotacja @ImplementatedBy informuje guice o klasie implementacji. W takim przypadku nie jest wymagane żadne powiązanie w module powiązania.
@ProvidedBy annotation Adnotacja @ProvidedBy informuje przewodnik o dostawcy klasy implementacji. W takim przypadku nie jest wymagane żadne powiązanie w module powiązania.

Konstruktory nieprywatne i bez argumentów kwalifikują się do powiązań just in time. Innym sposobem jest dodanie adnotacji do konstruktora za pomocą adnotacji @Inject. Zobacz przykład:

Przykład

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   public TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() { 
      bind(SpellChecker.class).to(SpellCheckerImpl.class);
      bind(String.class)
         .annotatedWith(Names.named("JDBC"))
         .toInstance("jdbc:mysql://localhost:5326/emp");
   } 
}

//spell checker interface
interface SpellChecker {
   public void checkSpelling();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Inject @Named("JDBC")
   private String dbUrl;

   public SpellCheckerImpl(){}

   @Override
   public void checkSpelling() { 
      System.out.println("Inside checkSpelling." );
      System.out.println(dbUrl); 
   }
}

Wynik

Skompiluj i uruchom plik, zobaczysz następujące dane wyjściowe.

Inside checkSpelling.
jdbc:mysql://localhost:5326/emp

Adnotacja @ImplementatedBy informuje guice o klasie implementacji. W takim przypadku nie jest wymagane żadne powiązanie w module powiązania. Zobacz przykład:

Przykład

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   public TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() { 
      bind(String.class)
         .annotatedWith(Names.named("JDBC"))
         .toInstance("jdbc:mysql://localhost:5326/emp");
   } 
}

@ImplementedBy(SpellCheckerImpl.class)
interface SpellChecker {
   public void checkSpelling();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Inject @Named("JDBC")
   private String dbUrl;

   public SpellCheckerImpl(){}

   @Override
   public void checkSpelling() { 
      System.out.println("Inside checkSpelling." );
      System.out.println(dbUrl); 
   }
}

Wynik

Skompiluj i uruchom plik, zobaczysz następujące dane wyjściowe.

Inside checkSpelling.
jdbc:mysql://localhost:5326/emp

Adnotacja @ProvidedBy informuje przewodnik o dostawcy klasy implementacji. W takim przypadku nie jest wymagane żadne powiązanie w module powiązania. Zobacz przykład:

Przykład

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.ProvidedBy;
import com.google.inject.Provider;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;
   @Inject
   public TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {     
   } 
}

@ProvidedBy(SpellCheckerProvider.class)
interface SpellChecker {
   public void checkSpelling();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   private String dbUrl;
   private String user;
   private Integer timeout;

   @Inject
   public SpellCheckerImpl(String dbUrl, 
      String user, 
      Integer timeout){
      this.dbUrl = dbUrl;
      this.user = user;
      this.timeout = timeout;
   } 

   @Override
   public void checkSpelling() { 
      System.out.println("Inside checkSpelling." );
      System.out.println(dbUrl);
      System.out.println(user);
      System.out.println(timeout);
   }
}

class SpellCheckerProvider implements Provider<SpellChecker>{

   @Override
   public SpellChecker get() {
      String dbUrl = "jdbc:mysql://localhost:5326/emp";
      String user = "user";
      int timeout = 100;

      SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
      return SpellChecker;
   }
}

Wynik

Skompiluj i uruchom plik, zobaczysz następujące dane wyjściowe.

Inside checkSpelling.
jdbc:mysql://localhost:5326/emp
user
100

Iniekcja to proces wstrzykiwania zależności do obiektu. Wstrzyknięcie konstruktora jest dość powszechne. W tym procesie zależność jest wprowadzana jako argument do konstruktora. Zobacz poniższy przykład.

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck(); 
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   public TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   }
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      bind(SpellChecker.class).to(SpellCheckerImpl.class);
   } 
}

//spell checker interface
interface SpellChecker {
   public void checkSpelling();
}


//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Override
   public void checkSpelling() {
      System.out.println("Inside checkSpelling." );
   } 
}

Wynik

Skompiluj i uruchom plik, zobaczysz następujące dane wyjściowe.

Inside checkSpelling.

Iniekcja to proces wstrzykiwania zależności do obiektu. Wstrzyknięcie metody służy do ustawiania obiektu wartości jako zależności od obiektu. Zobacz poniższy przykład.

Przykład

Utwórz klasę Java o nazwie GuiceTester.

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   public TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() { 
      bind(String.class)
         .annotatedWith(Names.named("JDBC"))
         .toInstance("jdbc:mysql://localhost:5326/emp");
   } 
}

@ImplementedBy(SpellCheckerImpl.class)
interface SpellChecker {
   public void checkSpelling();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
 
   private String dbUrl;

   public SpellCheckerImpl(){}
   
   @Inject 
   public void setDbUrl(@Named("JDBC") String dbUrl){
      this.dbUrl = dbUrl;
   }

   @Override
   public void checkSpelling() { 
      System.out.println("Inside checkSpelling." );
      System.out.println(dbUrl); 
   }
}

Wynik

Skompiluj i uruchom plik, zobaczysz następujące dane wyjściowe.

Inside checkSpelling.
jdbc:mysql://localhost:5326/emp

Iniekcja to proces wstrzykiwania zależności do obiektu. Wstrzyknięcie pola służy do ustawienia obiektu wartości jako zależności od pola obiektu. Zobacz poniższy przykład.

Przykład

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   public TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() { 
      bind(String.class)
         .annotatedWith(Names.named("JDBC"))
         .toInstance("jdbc:mysql://localhost:5326/emp");
   } 
}

@ImplementedBy(SpellCheckerImpl.class)
interface SpellChecker {
   public void checkSpelling();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Inject @Named("JDBC")
   private String dbUrl;

   public SpellCheckerImpl(){}

   @Override
   public void checkSpelling() { 
      System.out.println("Inside checkSpelling." );
      System.out.println(dbUrl); 
   }
}

Wynik

Skompiluj i uruchom plik, zobaczysz następujące dane wyjściowe.

Inside checkSpelling.
jdbc:mysql://localhost:5326/emp

Iniekcja to proces wstrzykiwania zależności do obiektu. Opcjonalne wstrzyknięcie oznacza wstrzyknięcie zależności, jeśli istnieje. Wstrzyknięcia metody i pola mogą być opcjonalnie zależne i powinny mieć pewną wartość domyślną, jeśli zależność nie jest obecna. Zobacz poniższy przykład.

Przykład

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   public TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {} 
}

@ImplementedBy(SpellCheckerImpl.class)
interface SpellChecker {
   public void checkSpelling();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   private String dbUrl = "jdbc:mysql://localhost:5326/emp";

   public SpellCheckerImpl(){}
   
   @Inject(optional=true)
   public void setDbUrl(@Named("JDBC") String dbUrl){
      this.dbUrl = dbUrl;
   }

   @Override
   public void checkSpelling() { 
      System.out.println("Inside checkSpelling." );
      System.out.println(dbUrl); 
   }
}

Wynik

Skompiluj i uruchom plik, zobaczysz następujące dane wyjściowe.

Inside checkSpelling.
jdbc:mysql://localhost:5326/emp

Iniekcja to proces wstrzykiwania zależności do obiektu. Wstrzyknięcia metody i pola mogą być użyte do zainicjowania obiektu wyjściowego przy użyciu metody injector.injectMembers () . Zobacz poniższy przykład.

Przykład

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
import com.google.inject.Injector;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      SpellChecker spellChecker = new SpellCheckerImpl();
      injector.injectMembers(spellChecker);
      
      TextEditor editor = injector.getInstance(TextEditor.class);     
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   public void setSpellChecker(SpellChecker spellChecker){
   this.spellChecker = spellChecker;
   }
   public TextEditor() { }

   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {      
   } 
}

@ImplementedBy(SpellCheckerImpl.class)
interface SpellChecker {
   public void checkSpelling();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   public SpellCheckerImpl(){}
   
   @Override
   public void checkSpelling() { 
      System.out.println("Inside checkSpelling." );
   }
}

Skompiluj i uruchom plik, zobaczysz następujące dane wyjściowe.

Inside checkSpelling.

Guice zwraca nową instancję za każdym razem, gdy dostarcza wartość jako domyślne zachowanie. Można go konfigurować za pomocą zakresów. Oto zakresy obsługiwane przez Guice:

  • @Singleton- Pojedyncza instancja na cały okres istnienia aplikacji. Obiekt @Singleton musi być bezpieczny dla wątków.

  • @SessionScoped- Pojedyncza instancja dla określonej sesji aplikacji internetowej. Obiekt @SessionScoped musi być bezpieczny wątkowo.

  • @RequestScoped- Pojedyncza instancja dla konkretnego żądania aplikacji internetowej. Obiekt @RequestScoped nie musi być wątkowo bezpieczny.

Sposób stosowania zakresów.

Poniżej przedstawiono sposoby stosowania zakresów.

Na poziomie klasy

@Singleton
class SpellCheckerImpl implements SpellChecker {

   public SpellCheckerImpl(){}
   
   @Override
   public void checkSpelling() { 
      System.out.println("Inside checkSpelling." );
   }
}

Na poziomie konfiguracji

bind(SpellChecker.class).to(SpellCheckerImpl.class).in(Singleton.class);

Na poziomie metody

@Provides @Singleton
public SpellChecker provideSpellChecker(){

   String dbUrl = "jdbc:mysql://localhost:5326/emp";
   String user = "user";
   int timeout = 100;

   SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
   return SpellChecker;
}

Przykład

Zobaczmy, jak działa Scope na poziomie klasy.

Wynik z adnotacją @Singleton

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      SpellChecker spellChecker = new SpellCheckerImpl();
      injector.injectMembers(spellChecker);

      TextEditor editor = injector.getInstance(TextEditor.class);     
      System.out.println(editor.getSpellCheckerId());

      TextEditor editor1 = injector.getInstance(TextEditor.class);     
      System.out.println(editor1.getSpellCheckerId());
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   public void setSpellChecker(SpellChecker spellChecker){
      this.spellChecker = spellChecker;
   }
   public TextEditor() { }

   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   } 

   public double getSpellCheckerId(){
      return spellChecker.getId();
   }
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {   
      bind(SpellChecker.class).to(SpellCheckerImpl.class);
   } 
}

interface SpellChecker {
   public double getId();
   public void checkSpelling();
}

@Singleton
class SpellCheckerImpl implements SpellChecker {

   double id; 
   public SpellCheckerImpl(){
      id = Math.random();    
   }

   @Override
   public void checkSpelling() { 
      System.out.println("Inside checkSpelling." );
   }

   @Override
   public double getId() { 
      return id;
   }
}

Skompiluj i uruchom plik, możesz zobaczyć następujące dane wyjściowe.

0.3055839187063575
0.3055839187063575

Wynik bez adnotacji @Singleton

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      SpellChecker spellChecker = new SpellCheckerImpl();
      injector.injectMembers(spellChecker);

      TextEditor editor = injector.getInstance(TextEditor.class);     
      System.out.println(editor.getSpellCheckerId());

      TextEditor editor1 = injector.getInstance(TextEditor.class);     
      System.out.println(editor1.getSpellCheckerId());
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   public void setSpellChecker(SpellChecker spellChecker){
      this.spellChecker = spellChecker;
   }
   public TextEditor() { }

   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   } 

   public double getSpellCheckerId(){
      return spellChecker.getId();
   }
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {   
      bind(SpellChecker.class).to(SpellCheckerImpl.class);
   } 
}

interface SpellChecker {
   public double getId();
   public void checkSpelling();
}

class SpellCheckerImpl implements SpellChecker {

   double id; 
   public SpellCheckerImpl(){
      id = Math.random();    
   }

   @Override
   public void checkSpelling() { 
      System.out.println("Inside checkSpelling." );
   }

   @Override
   public double getId() { 
      return id;
   }
}

Skompiluj i uruchom plik, możesz zobaczyć następujące dane wyjściowe.

0.556007079571739
0.22095011760351602

Google Guice - AOP

AOP, programowanie zorientowane na aspekt polega na rozbiciu logiki programu na odrębne części zwane tak zwanymi problemami. Funkcje, które obejmują wiele punktów aplikacji, nazywane są zagadnieniami przekrojowymi, a te zagadnienia przekrojowe są koncepcyjnie oddzielone od logiki biznesowej aplikacji. Istnieje wiele typowych dobrych przykładów aspektów, takich jak logowanie, audyt, transakcje deklaratywne, bezpieczeństwo, buforowanie itp.

Kluczową jednostką modułowości w OOP jest klasa, podczas gdy w AOP jednostką modułowości jest aspekt. Dependency Injection pomaga oddzielić obiekty aplikacji od siebie, a AOP pomaga oddzielić problemy związane z cięciem krzyżowym od obiektów, na które mają one wpływ. AOP jest jak wyzwalacze w językach programowania, takich jak Perl, .NET, Java i inne. Guice zapewnia przechwytywacze do przechwytywania aplikacji. Na przykład, gdy metoda jest wykonywana, możesz dodać dodatkowe funkcje przed lub po wykonaniu metody.

Ważne zajęcia

  • Matcher- Matcher to interfejs do akceptowania lub odrzucania wartości. W Guice AOP potrzebujemy dwóch dopasowań: jednego do określenia, które klasy uczestniczą, a drugiego do metod tych klas.

  • MethodInterceptor- MethodInterceptors są wykonywane, gdy wywoływana jest metoda dopasowania. Mogą sprawdzić wywołanie: metodę, jej argumenty i instancję odbierającą. Możemy wykonać logikę przekrojową, a następnie delegować do metody bazowej. Na koniec możemy sprawdzić zwracaną wartość lub wyjątek i zwrócić.

Przykład

Utwórz klasę Java o nazwie GuiceTester.

GuiceTester.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.matcher.Matchers;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck(); 
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   public TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   }
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      bind(SpellChecker.class).to(SpellCheckerImpl.class);
      bindInterceptor(Matchers.any(), 
         Matchers.annotatedWith(CallTracker.class), 
         new CallTrackerService());
   } 
}

//spell checker interface
interface SpellChecker {
   public void checkSpelling();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Override @CallTracker
   public void checkSpelling() {
      System.out.println("Inside checkSpelling." );
   } 
}

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD)
@interface CallTracker {}

class CallTrackerService implements MethodInterceptor  {

   @Override
   public Object invoke(MethodInvocation invocation) throws Throwable {
      System.out.println("Before " + invocation.getMethod().getName());
      Object result = invocation.proceed();
      System.out.println("After " + invocation.getMethod().getName());
      return result;
   }
}

Skompiluj i uruchom plik, możesz zobaczyć następujące dane wyjściowe.

Before checkSpelling
Inside checkSpelling.
After checkSpelling