Учебники

Google Guice — Краткое руководство

Google Guice — Обзор

Guice — это среда внедрения зависимостей на основе Java с открытым исходным кодом. Это тихий легкий и активно разрабатывается / управляется Google.

Внедрение зависимости

Каждое Java-приложение имеет несколько объектов, которые работают вместе, чтобы представить то, что конечный пользователь видит в качестве рабочего приложения. При написании сложного Java-приложения классы приложения должны быть как можно более независимыми от других Java-классов, чтобы увеличить возможность повторного использования этих классов и тестировать их независимо от других классов во время модульного тестирования. Инъекция зависимостей (или иногда называемая проводкой) помогает склеивать эти классы и в то же время сохранять их независимость.

Предположим, у вас есть приложение, в котором есть компонент текстового редактора, и вы хотите обеспечить проверку орфографии. Ваш стандартный код будет выглядеть примерно так:

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

Здесь мы создали зависимость между TextEditor и SpellChecker. В сценарии инверсии управления мы вместо этого сделали бы что-то вроде этого —

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

Здесь TextEditor не должен беспокоиться о реализации SpellChecker. SpellChecker будет реализован независимо и будет предоставлен TextEditor во время создания экземпляра TextEditor.

Инъекция зависимостей с использованием Guice (Binding)

Инъекция зависимостей контролируется привязками Guice. Guice использует привязки для отображения типов объектов на их фактические реализации. Эти привязки определены модулем. Модуль представляет собой набор привязок, как показано ниже —

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);
   }
}

Модуль является основным строительным блоком для Инжектора, который является создателем графов объектов Guice. Первый шаг — создать инжектор, а затем мы можем использовать инжектор, чтобы получить объекты.

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);   
}

В вышеприведенном примере граф объектов класса TextEditor создается Guice, и этот граф содержит объект TextEditor и его зависимость как объект WinWordSpellChecker.

Google Guice — Настройка среды

Настройка локальной среды

Если вы все еще хотите настроить свою среду для языка программирования Java, то в этом разделе вы узнаете, как загрузить и настроить Java на вашем компьютере. Пожалуйста, следуйте инструкциям ниже, чтобы настроить среду.

Java SE находится в свободном доступе по ссылке Скачать Java . Таким образом, вы загружаете версию, основанную на вашей операционной системе.

Следуйте инструкциям для загрузки Java и запуска .exe для установки Java на вашем компьютере. После того, как вы установили Java на свой компьютер, вам нужно будет установить переменные окружения, чтобы они указывали на правильные каталоги установки —

Настройка пути для Windows 2000 / XP

Мы предполагаем, что вы установили Java в каталог c: \ Program Files \ java \ jdk

  • Щелкните правой кнопкой мыши «Мой компьютер» и выберите «Свойства».

  • Нажмите кнопку «Переменные среды» на вкладке «Дополнительно».

  • Теперь измените переменную Path, чтобы она также содержала путь к исполняемому файлу Java. Например, если в настоящий момент путь задан как «C: \ WINDOWS \ SYSTEM32», измените ваш путь на «C: \ WINDOWS \ SYSTEM32; c: \ Program Files \ java \ jdk \ bin».

Щелкните правой кнопкой мыши «Мой компьютер» и выберите «Свойства».

Нажмите кнопку «Переменные среды» на вкладке «Дополнительно».

Теперь измените переменную Path, чтобы она также содержала путь к исполняемому файлу Java. Например, если в настоящий момент путь задан как «C: \ WINDOWS \ SYSTEM32», измените ваш путь на «C: \ WINDOWS \ SYSTEM32; c: \ Program Files \ java \ jdk \ bin».

Настройка пути для Windows 95/98 / ME

Мы предполагаем, что вы установили Java в каталог c: \ Program Files \ java \ jdk

  • Отредактируйте файл «C: \ autoexec.bat» и добавьте в конце следующую строку: «SET PATH =% PATH%; C: \ Program Files \ java \ jdk \ bin».

Отредактируйте файл «C: \ autoexec.bat» и добавьте в конце следующую строку: «SET PATH =% PATH%; C: \ Program Files \ java \ jdk \ bin».

Настройка пути для Linux, UNIX, Solaris, FreeBSD

Переменная среды PATH должна указывать на то, где установлены двоичные файлы Java. Обратитесь к документации по вашей оболочке, если у вас возникли проблемы с этим.

Например, если вы используете bash в качестве оболочки, вы добавили бы следующую строку в конец вашего ‘.bashrc: export PATH = / path / to / java: $ PATH’.

Популярные редакторы Java

Для написания ваших программ на Java вам нужен текстовый редактор. Есть много сложных IDE, доступных на рынке. Но сейчас вы можете рассмотреть один из следующих —

  • Блокнот — на компьютере с Windows вы можете использовать любой простой текстовый редактор, например Блокнот (рекомендуется для этого урока), TextPad.

  • Netbeans — это Java IDE с открытым исходным кодом, который можно загрузить по адресу https://www.netbeans.org/index.html .

  • Eclipse — это также Java IDE, разработанная сообществом открытого исходного кода eclipse, которую можно скачать по адресу https://www.eclipse.org/ .

Блокнот — на компьютере с Windows вы можете использовать любой простой текстовый редактор, например Блокнот (рекомендуется для этого урока), TextPad.

Netbeans — это Java IDE с открытым исходным кодом, который можно загрузить по адресу https://www.netbeans.org/index.html .

Eclipse — это также Java IDE, разработанная сообществом открытого исходного кода eclipse, которую можно скачать по адресу https://www.eclipse.org/ .

Google Guice Environment

Загрузите последнюю версию Google Guice и связанные файлы JAR.

Google Guice 4.0

АОП Альянс 1.0

Гуава 16.0.1

javax.inject 1.0

На момент написания этого руководства мы скопировали их в папку C: \> Google.

Операционные системы Название архива
Windows Guice-4.1.0.jar; aopalliance-1.0.jar; гуавы-16.0.1.jar; javax.inject-1.jar
Linux Guice-4.1.0.jar; aopalliance-1.0.jar; гуавы-16.0.1.jar; javax.inject-1.jar
макинтош Guice-4.1.0.jar; aopalliance-1.0.jar; гуавы-16.0.1.jar; javax.inject-1.jar

Установить переменную CLASSPATH

Задайте переменную среды CLASSPATH, чтобы она указывала на расположение баночки Guice. Предполагается, что вы сохранили Guice и связанные файлы в папке Google в различных операционных системах следующим образом.

Операционные системы Выход
Windows Установите для переменной среды CLASSPATH значение% 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 :.
макинтош 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 :.

Google Guice — первое приложение

Давайте создадим пример консольного приложения, в котором мы шаг за шагом продемонстрируем внедрение зависимостей, используя механизм привязки Guice.

Шаг 1: Создать интерфейс

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

Шаг 2: Создать реализацию

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

Шаг 3. Создание модуля привязок

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

Шаг 4: Создать класс с зависимостью

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

Шаг 5: Создать инжектор

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

Шаг 6: Получить объект с выполненной зависимостью

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

Шаг 7: Используйте объект

editor.makeSpellCheck(); 

Полный пример

Создайте Java-класс с именем 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." );
   } 
}

Выход

Скомпилируйте и запустите файл, вы увидите следующий вывод.

Inside checkSpelling.

Google Guice — Связанная привязка

В связанных привязках Guice отображает тип на его реализацию. В приведенном ниже примере мы сопоставили интерфейс SpellChecker с его реализацией SpellCheckerImpl.

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

Мы также можем сопоставить конкретный класс с его подклассом. Смотрите пример ниже —

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

Здесь мы связали цепи. Давайте посмотрим на результат в полном примере.

Полный пример

Создайте Java-класс с именем 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." );
   } 
}

Выход

Скомпилируйте и запустите файл, вы увидите следующий вывод.

Inside WinWordSpellCheckerImpl.checkSpelling.

Google Guice — Обязательные аннотации

Как мы можем связать тип с его реализацией. В случае, если мы хотим отобразить тип с несколькими реализациями, мы также можем создать собственную аннотацию. Смотрите ниже пример, чтобы понять концепцию.

Создать обязательную аннотацию

@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
@interface WinWord {}
  • @BindingAnnotation — отмечает аннотацию как обязательную аннотацию.

  • @Target — Отмечает применимость аннотации.

  • @Retention — отмечает наличие аннотации как среды выполнения.

@BindingAnnotation — отмечает аннотацию как обязательную аннотацию.

@Target — Отмечает применимость аннотации.

@Retention — отмечает наличие аннотации как среды выполнения.

Картирование с использованием аннотации привязки

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

Внедрить с помощью аннотации

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

Полный пример

Создайте Java-класс с именем 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." );
   } 
}

Выход

Скомпилируйте и запустите файл, вы увидите следующий вывод.

Inside WinWordSpellCheckerImpl.checkSpelling.

Google Guice — @Named Binding

Guice предоставляет еще один способ сопоставления привязок без создания собственной аннотации. Это позволяет использовать аннотацию @Named.

Отображение с использованием именованной аннотации

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

Внедрить с помощью аннотации @Named

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

Полный пример

Создайте Java-класс с именем 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." );
   } 
}

Выход

Скомпилируйте и запустите файл, вы увидите следующий вывод.

Inside OpenOfficeWordSpellCheckerImpl.checkSpelling.

Google Guice — Постоянные привязки

Guice предоставляет способ создания привязок с объектами значений или константами. Рассмотрим случай, когда мы хотим настроить URL JDBC.

Внедрить с помощью аннотации @Named

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

Это может быть достигнуто с помощью метода toInstance ().

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

Полный пример

Создайте Java-класс с именем 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");
   } 
}

Выход

Скомпилируйте и запустите файл, вы увидите следующий вывод.

jdbc:mysql://localhost:5326/emp

Google Guice — @ Предоставляет аннотацию

,

Guice предоставляет способ создания привязок со сложными объектами с помощью метода @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;
}

Этот метод является частью Binding Module и предоставляет сложный объект для отображения. Смотрите полный пример ниже.

Полный пример

Создайте Java-класс с именем 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);
   }
}

Выход

Скомпилируйте и запустите файл, вы увидите следующий вывод.

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

Google Guice — класс провайдеров

Поскольку метод @provides становится более сложным, эти методы можно перемещать в отдельные классы с помощью интерфейса провайдера.

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;
   } 
}

Следующим шагом является сопоставление поставщика с типом.

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

Смотрите полный пример ниже.

Полный пример

Создайте Java-класс с именем 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;
   }
}

Выход

Скомпилируйте и запустите файл, вы увидите следующий вывод.

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

Google Guice — Привязки конструктора

Guice предоставляет способ создания привязок с конкретным конструктором объекта с помощью метода 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");
   } 
} 

Смотрите полный пример ниже.

Полный пример

Создайте Java-класс с именем 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); 
   }
}

Выход

Скомпилируйте и запустите файл, вы увидите следующий вывод.

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

Google Guice — встроенные привязки

Guice предоставляет встроенную привязку для класса java.util.logging.Logger . Имя регистратора автоматически устанавливается на имя класса, в который вводится регистратор. Смотрите пример ниже.

пример

Создайте Java-класс с именем 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() {
   } 
}

Выход

Скомпилируйте и запустите файл, вы увидите следующий вывод.

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

Google Guice — привязки точно в срок

Поскольку привязки определены в модуле связывания, Guice использует их всякий раз, когда необходимо внедрить зависимости. В случае отсутствия привязок он может попытаться создать привязки точно в срок. Привязки, присутствующие в модуле привязки, называются явными привязками и имеют более высокий приоритет, тогда как привязки точно в срок называются неявными привязками. Если присутствуют оба типа привязок, для отображения рассматриваются явные привязки.

Ниже приведены примеры трех типов привязок «точно в срок».

Sr.No. Тип и описание привязки
1 Инъекционные Конструкторы

Не частные, конструкторы без аргументов имеют право на привязки точно в срок. Другой способ — аннотировать конструктор аннотацией @Inject.

2 @ImplementatedBy аннотация

Аннотация @ImplementatedBy рассказывает об классе реализации. В этом случае связывание в модуле связывания не требуется.

3 @ProvidedBy аннотация

Аннотация @ProvidedBy рассказывает о поставщике класса реализации. В этом случае связывание в модуле связывания не требуется.

Не частные, конструкторы без аргументов имеют право на привязки точно в срок. Другой способ — аннотировать конструктор аннотацией @Inject.

Аннотация @ImplementatedBy рассказывает об классе реализации. В этом случае связывание в модуле связывания не требуется.

Аннотация @ProvidedBy рассказывает о поставщике класса реализации. В этом случае связывание в модуле связывания не требуется.

Google Guice — Внедрение в конструктор

Инъекция — это процесс внедрения зависимости в объект. Конструктор инъекций встречается довольно часто. В этом процессе зависимость вводится в качестве аргумента в конструктор. Смотрите пример ниже.

Создайте Java-класс с именем 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." );
   } 
}

Выход

Скомпилируйте и запустите файл, вы увидите следующий вывод.

Inside checkSpelling.

Google Guice — метод внедрения

Инъекция — это процесс внедрения зависимости в объект. Внедрение метода используется для установки значения объекта как зависимости от объекта. Смотрите пример ниже.

пример

Создайте Java-класс с именем 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); 
   }
}

Выход

Скомпилируйте и запустите файл, вы увидите следующий вывод.

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

Google Guice — Field Injection

Инъекция — это процесс внедрения зависимости в объект. Внедрение поля используется для установки значения объекта как зависимости от поля объекта. Смотрите пример ниже.

пример

Создайте Java-класс с именем 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); 
   }
}

Выход

Скомпилируйте и запустите файл, вы увидите следующий вывод.

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

Google Guice — опциональная инъекция

Инъекция — это процесс внедрения зависимости в объект. Необязательное внедрение означает внедрение зависимости, если она существует. Инъекции метода и поля могут быть необязательно зависимыми и должны иметь некоторое значение по умолчанию, если зависимость отсутствует. Смотрите пример ниже.

пример

Создайте Java-класс с именем 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); 
   }
}

Выход

Скомпилируйте и запустите файл, вы увидите следующий вывод.

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

Google Guice — инъекция по требованию

Инъекция — это процесс внедрения зависимости в объект. Инъекции метода и поля можно использовать для инициализации, используя выход из объекта, используя метод injector.injectMembers () . Смотрите пример ниже.

пример

Создайте Java-класс с именем 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." );
   }
}

Скомпилируйте и запустите файл, вы увидите следующий вывод.

Inside checkSpelling.

Google Guice — Области применения

Guice возвращает новый экземпляр каждый раз, когда он задает значение в качестве поведения по умолчанию. Это настраивается с помощью областей. Ниже приведены области, которые поддерживает Guice.

  • @Singleton — один экземпляр на весь срок действия приложения. Объект @Singleton должен быть потокобезопасным.

  • @SessionScoped — один экземпляр для определенного сеанса веб-приложения. Объект @SessionScoped должен быть потокобезопасным.

  • @RequestScoped — один экземпляр для конкретного запроса веб-приложения. Объект @RequestScoped не должен быть потокобезопасным.

@Singleton — один экземпляр на весь срок действия приложения. Объект @Singleton должен быть потокобезопасным.

@SessionScoped — один экземпляр для определенного сеанса веб-приложения. Объект @SessionScoped должен быть потокобезопасным.

@RequestScoped — один экземпляр для конкретного запроса веб-приложения. Объект @RequestScoped не должен быть потокобезопасным.

Способ применения областей

Ниже приведены способы применения областей.

На уровне класса

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

На уровне конфигурации

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

На уровне метода

@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;
}

пример

Давайте посмотрим Scope на уровне класса в действии.

Результат с аннотацией @Singleton

Создайте Java-класс с именем 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;
   }
}

Скомпилируйте и запустите файл, вы можете увидеть следующий вывод с теми же номерами.

0.3055839187063575
0.3055839187063575

Результат без аннотации @Singleton

Создайте Java-класс с именем 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;
   }
}

Скомпилируйте и запустите файл, вы можете увидеть следующий вывод с разными номерами.

0.556007079571739
0.22095011760351602

Google Guice — AOP

АОП, Аспектно-ориентированное программирование влечет за собой разбиение логики программы на отдельные части, называемые так называемыми проблемами. Функции, охватывающие несколько точек приложения, называются сквозными задачами, и эти сквозные задачи концептуально отделены от бизнес-логики приложения. Существуют различные общие хорошие примеры таких аспектов, как ведение журнала, аудит, декларативные транзакции, безопасность, кэширование и т. Д.

Ключевой единицей модульности в ООП является класс, тогда как в АОП единицей модульности является аспект. Внедрение зависимостей помогает отделить объекты приложения друг от друга, а AOP помогает отделить сквозные задачи от объектов, на которые они влияют. AOP подобен триггерам в таких языках программирования, как Perl, .NET, Java и других. Guice предоставляет перехватчики для перехвата приложения. Например, когда метод выполняется, вы можете добавить дополнительные функции до или после выполнения метода.

Важные классы

  • Matcher — Matcher — это интерфейс для принятия или отклонения значения. В Guice AOP нам нужны два сопоставителя: один для определения участвующих классов, а другой для методов этих классов.

  • MethodInterceptor — MethodInterceptors выполняются, когда вызывается соответствующий метод. Они могут проверить вызов: метод, его аргументы и получающий экземпляр. Мы можем выполнить сквозную логику, а затем делегировать базовый метод. Наконец, мы можем проверить возвращаемое значение или исключение и вернуть.

Matcher — Matcher — это интерфейс для принятия или отклонения значения. В Guice AOP нам нужны два сопоставителя: один для определения участвующих классов, а другой для методов этих классов.

MethodInterceptor — MethodInterceptors выполняются, когда вызывается соответствующий метод. Они могут проверить вызов: метод, его аргументы и получающий экземпляр. Мы можем выполнить сквозную логику, а затем делегировать базовый метод. Наконец, мы можем проверить возвращаемое значение или исключение и вернуть.

пример

Создайте Java-класс с именем 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;
   }
}

Скомпилируйте и запустите файл, вы можете увидеть следующий вывод.