Google Guice - Hướng dẫn nhanh

Guice là một khuôn khổ tiêm phụ thuộc mã nguồn mở, dựa trên Java. Nó nhẹ và yên tĩnh và được phát triển / quản lý bởi Google.

Tiêm phụ thuộc

Mỗi ứng dụng dựa trên Java đều có một vài đối tượng hoạt động cùng nhau để trình bày những gì người dùng cuối coi là một ứng dụng đang hoạt động. Khi viết một ứng dụng Java phức tạp, các lớp ứng dụng phải độc lập nhất có thể với các lớp Java khác để tăng khả năng sử dụng lại các lớp này và kiểm tra chúng độc lập với các lớp khác trong khi kiểm thử đơn vị. Dependency Injection (hay đôi khi được gọi là nối dây) giúp dán các lớp này lại với nhau và đồng thời giữ chúng độc lập.

Hãy xem xét bạn có một ứng dụng có thành phần soạn thảo văn bản và bạn muốn cung cấp tính năng kiểm tra chính tả. Mã chuẩn của bạn sẽ trông giống như thế này -

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

Những gì chúng tôi đã làm ở đây là tạo sự phụ thuộc giữa TextEditor và SpellChecker. Trong một kịch bản điều khiển đảo ngược, thay vào đó chúng tôi sẽ làm điều gì đó như thế này -

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

Ở đây, TextEditor không nên lo lắng về việc triển khai SpellChecker. SpellChecker sẽ được triển khai độc lập và sẽ được cung cấp cho TextEditor tại thời điểm khởi tạo TextEditor.

Dependency Injection sử dụng Guice (Binding)

Dependency Injection được kiểm soát bởi Guice Bindings. Guice sử dụng các ràng buộc để ánh xạ các loại đối tượng với các triển khai thực tế của chúng. Các ràng buộc này được xác định một mô-đun. Mô-đun là một tập hợp các ràng buộc như hình dưới đây:

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

Mô-đun là khối xây dựng cốt lõi cho một Injector là trình tạo đồ thị đối tượng của Guice. Bước đầu tiên là tạo một kim phun và sau đó chúng ta có thể sử dụng kim phun để lấy các đối tượng.

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

Trong ví dụ trên, đồ thị đối tượng lớp TextEditor được Guice xây dựng và đồ thị này chứa đối tượng TextEditor và sự phụ thuộc của nó là đối tượng WinWordSpellChecker.

Thiết lập môi trường cục bộ

Nếu bạn vẫn sẵn sàng thiết lập môi trường của mình cho ngôn ngữ lập trình Java, thì phần này sẽ hướng dẫn bạn cách tải xuống và thiết lập Java trên máy của bạn. Vui lòng làm theo các bước được đề cập bên dưới để thiết lập môi trường.

Java SE có sẵn miễn phí từ liên kết Tải xuống Java . Vì vậy, bạn tải xuống một phiên bản dựa trên hệ điều hành của bạn.

Làm theo hướng dẫn để tải xuống Java và chạy .exeđể cài đặt Java trên máy của bạn. Khi bạn đã cài đặt Java trên máy của mình, bạn sẽ cần đặt các biến môi trường để trỏ đến các thư mục cài đặt chính xác -

Thiết lập đường dẫn cho Windows 2000 / XP

Chúng tôi giả định rằng bạn đã cài đặt Java trong thư mục c: \ Program Files \ java \ jdk -

  • Nhấp chuột phải vào 'Máy tính của tôi' và chọn 'Thuộc tính'.

  • Nhấp vào nút 'Biến môi trường' trong tab 'Nâng cao'.

  • Bây giờ, hãy thay đổi biến 'Đường dẫn' để nó cũng chứa đường dẫn đến tệp thực thi Java. Ví dụ, nếu đường dẫn hiện được đặt thành 'C: \ WINDOWS \ SYSTEM32', thì hãy thay đổi đường dẫn của bạn thành 'C: \ WINDOWS \ SYSTEM32; c: \ Program Files \ java \ jdk \ bin'.

Thiết lập đường dẫn cho Windows 95/98 / ME

Chúng tôi giả định rằng bạn đã cài đặt Java trong thư mục c: \ Program Files \ java \ jdk -

  • Chỉnh sửa tệp 'C: \ autoexec.bat' và thêm dòng sau vào cuối - 'SET PATH =% PATH%; C: \ Program Files \ java \ jdk \ bin'

Thiết lập đường dẫn cho Linux, UNIX, Solaris, FreeBSD

Biến môi trường PATH nên được đặt để trỏ đến nơi các tệp nhị phân Java đã được cài đặt. Tham khảo tài liệu shell của bạn nếu bạn gặp khó khăn khi thực hiện việc này.

Ví dụ: nếu bạn sử dụng bash làm trình bao, thì bạn sẽ thêm dòng sau vào cuối '.bashrc: export PATH = / path / to / java: $ PATH'

Trình chỉnh sửa Java phổ biến

Để viết các chương trình Java, bạn cần một trình soạn thảo văn bản. Có rất nhiều IDE tinh vi có sẵn trên thị trường. Nhưng hiện tại, bạn có thể xem xét một trong những điều sau:

  • Notepad - Trên máy Windows, bạn có thể sử dụng bất kỳ trình soạn thảo văn bản đơn giản nào như Notepad (Khuyến nghị cho hướng dẫn này), TextPad.

  • Netbeans - Đây là một IDE Java mã nguồn mở và miễn phí có thể được tải xuống từ https://www.netbeans.org/index.html.

  • Eclipse - Nó cũng là một IDE Java được phát triển bởi cộng đồng nguồn mở eclipse và có thể được tải xuống từ https://www.eclipse.org/.

Môi trường Guice của Google

Tải xuống phiên bản mới nhất của Google Guice và các tệp jar liên quan.

  • Google Guice 4.0

  • AOP Alliance 1.0

  • Ổi 16.0.1

  • javax.inject 1.0

Tại thời điểm viết hướng dẫn này, chúng tôi đã sao chép chúng vào thư mục C: \> Google.

Hệ điều hành Tên lưu trữ
các cửa sổ guice-4.1.0.jar; aopalliance-1.0.jar; ổi-16.0.1.jar; javax.inject-1.jar
Linux guice-4.1.0.jar; aopalliance-1.0.jar; ổi-16.0.1.jar; javax.inject-1.jar
Mac guice-4.1.0.jar; aopalliance-1.0.jar; ổi-16.0.1.jar; javax.inject-1.jar

Đặt biến CLASSPATH

Đặt CLASSPATHbiến môi trường để trỏ đến vị trí của Guice jar. Giả sử, bạn đã lưu trữ Guice và các lọ liên quan trong thư mục Google trên các Hệ điều hành khác nhau như sau.

Hệ điều hành Đầu ra
các cửa sổ Đặt biến môi trường CLASSPATH thành% CLASSPATH%; C: \ Google \ guice-4.1.0.jar; C: \ Google \ aopalliance-1.0.jar; C: \ Google \ ổi-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 / ổi-16.0.1.jar: Google / javax.inject-1.jar :.
Mac export CLASSPATH = $ CLASSPATH: Google / guice-4.1.0.jar: Google / aopalliance-1.0.jar: Google / ổi-16.0.1.jar: Google / javax.inject-1.jar :.

Hãy tạo một ứng dụng dựa trên bảng điều khiển mẫu, nơi chúng tôi sẽ chứng minh việc tiêm phụ thuộc bằng cách sử dụng cơ chế liên kết Guice từng bước.

Bước 1: Tạo giao diện

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

Bước 2: Tạo triển khai

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

Bước 3: Tạo mô-đun ràng buộc

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

Bước 4: Tạo lớp phụ thuộc

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

Bước 5: Tạo Injector

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

Bước 6: Lấy đối tượng với sự phụ thuộc được đáp ứng.

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

Bước 7: Sử dụng đối tượng.

editor.makeSpellCheck();

Hoàn thành ví dụ

Tạo một lớp java có tên là 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." );
   } 
}

Đầu ra

Biên dịch và chạy tệp, bạn sẽ thấy kết quả sau.

Inside checkSpelling.

Trong Các ràng buộc được liên kết, Guice ánh xạ một kiểu để triển khai nó. Trong ví dụ dưới đây, chúng tôi đã ánh xạ giao diện SpellChecker với việc triển khai SpellCheckerImpl.

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

Chúng ta cũng có thể ánh xạ lớp cụ thể với lớp con của nó. Xem ví dụ dưới đây:

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

Ở đây chúng tôi đã xâu chuỗi các ràng buộc. Hãy xem kết quả trong ví dụ đầy đủ.

Hoàn thành ví dụ

Tạo một lớp java có tên là 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." );
   } 
}

Đầu ra

Biên dịch và chạy tệp, bạn sẽ thấy kết quả sau.

Inside WinWordSpellCheckerImpl.checkSpelling.

Vì chúng ta có thể ràng buộc một kiểu với việc triển khai nó. Trong trường hợp chúng tôi muốn ánh xạ một loại có nhiều điểm ghép, chúng tôi cũng có thể tạo chú thích tùy chỉnh. Xem ví dụ dưới đây để hiểu khái niệm.

Tạo chú thích ràng buộc

@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
@interface WinWord {}
  • @BindingAnnotation - Đánh dấu chú thích là chú thích ràng buộc.

  • @Target - Đánh dấu khả năng ứng dụng của chú thích.

  • @Retention - Đánh dấu tính khả dụng của chú thích là thời gian chạy.

Ánh xạ bằng cách sử dụng chú thích ràng buộc

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

Tiêm bằng cách sử dụng chú thích ràng buộc

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

Hoàn thành ví dụ

Tạo một lớp java có tên là 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." );
   } 
}

Đầu ra

Biên dịch và chạy tệp, bạn sẽ thấy kết quả sau.

Inside WinWordSpellCheckerImpl.checkSpelling.

Guice cung cấp một cách khác để ánh xạ các ràng buộc mà không cần tạo thông báo tùy chỉnh. Nó cho phép sử dụng chú thích @Named.

Ánh xạ bằng cách sử dụng chú thích được đặt tên

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

Tiêm bằng cách sử dụng chú thích @Named

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

Hoàn thành ví dụ

Tạo một lớp java có tên là 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." );
   } 
}

Đầu ra

Biên dịch và chạy tệp, bạn sẽ thấy kết quả sau.

Inside OpenOfficeWordSpellCheckerImpl.checkSpelling.

Guice cung cấp một cách để tạo liên kết với các đối tượng hoặc hằng giá trị. Hãy xem xét trường hợp chúng ta muốn định cấu hình url JDBC.

Tiêm bằng cách sử dụng chú thích @Named

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

Điều này có thể được thực hiện bằng cách sử dụng phương thức toInstance ().

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

Hoàn thành ví dụ

Tạo một lớp java có tên là 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");
   } 
}

Đầu ra

Biên dịch và chạy tệp, bạn sẽ thấy kết quả sau.

jdbc:mysql://localhost:5326/emp

Guice cung cấp cách tạo liên kết với các đối tượng phức tạp bằng phương thức @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;
}

Méthos này là một phần của Mô-đun ràng buộc và cung cấp đối tượng phức tạp được ánh xạ. Xem ví dụ đầy đủ bên dưới.

Hoàn thành ví dụ

Tạo một lớp java có tên là 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);
   }
}

Đầu ra

Biên dịch và chạy tệp, bạn sẽ thấy kết quả sau.

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

Khi phương thức @provides trở nên phức tạp hơn, các phương thức này có thể được chuyển sang các lớp riêng biệt bằng giao diện Nhà cung cấp.

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

Bước tiếp theo là ánh xạ nhà cung cấp để nhập.

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

Xem ví dụ đầy đủ bên dưới.

Hoàn thành ví dụ

Tạo một lớp java có tên là 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;
   }
}

Đầu ra

Biên dịch và chạy tệp, bạn sẽ thấy kết quả sau.

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

Guice cung cấp một cách để tạo các ràng buộc với hàm tạo cụ thể của một đối tượng bằng phương thức 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");
   } 
}

Xem ví dụ đầy đủ bên dưới.

Hoàn thành ví dụ

Tạo một lớp java có tên là 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); 
   }
}

Đầu ra

Biên dịch và chạy tệp, bạn sẽ thấy kết quả sau.

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

Guice cung cấp ràng buộc sẵn có cho lớp java.util.logging.Logger . Tên của Logger được tự động đặt thành tên của lớp mà Logger được đưa vào. Xem ví dụ bên dưới.

Thí dụ

Tạo một lớp java có tên là 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() {
   } 
}

Đầu ra

Biên dịch và chạy tệp, bạn sẽ thấy kết quả sau.

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

Vì các ràng buộc được định nghĩa trong Mô-đun ràng buộc, Guice sử dụng chúng bất cứ khi nào nó cần đưa các phụ thuộc vào. Trong trường hợp các ràng buộc không có mặt, nó có thể cố gắng tạo các ràng buộc đúng lúc. Các ràng buộc hiện diện trong mô-đun ràng buộc được gọi là ràng buộc rõ ràng và được ưu tiên cao hơn trong khi các ràng buộc chỉ trong thời gian được gọi là ràng buộc ngầm định. Nếu cả hai loại liên kết đều tồn tại, các liên kết rõ ràng được xem xét để ánh xạ.

Sau đây là các ví dụ về ba loại ràng buộc Just-in-time.

Loại ràng buộc Sự miêu tả
Các nhà xây dựng có thể tiêm Các hàm tạo không riêng tư, Không có đối số đủ điều kiện cho các ràng buộc đúng lúc. Một cách khác là chú thích một hàm tạo bằng chú thích @Inject.
@ImplementatedBy chú thích @ImplementatedBy chú thích cho biết chiêu bài về lớp triển khai. Không cần ràng buộc trong Mô-đun ràng buộc trong trường hợp như vậy.
@ProvidedBy chú thích @ProvidedBy chú thích cho biết chiêu bài về nhà cung cấp lớp triển khai. Không cần ràng buộc trong Mô-đun ràng buộc trong trường hợp như vậy.

Các hàm tạo không riêng tư, Không có đối số đủ điều kiện cho các ràng buộc đúng lúc. Một cách khác là chú thích một hàm tạo bằng chú thích @Inject. Xem ví dụ:

Thí dụ

Tạo một lớp java có tên là 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); 
   }
}

Đầu ra

Biên dịch và chạy tệp, bạn sẽ thấy kết quả sau.

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

@ImplementatedBy chú thích cho biết chiêu bài về lớp triển khai. Không cần ràng buộc trong Mô-đun ràng buộc trong trường hợp như vậy. Xem ví dụ:

Thí dụ

Tạo một lớp java có tên là 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); 
   }
}

Đầu ra

Biên dịch và chạy tệp, bạn sẽ thấy kết quả sau.

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

@ProvidedBy chú thích cho biết chiêu bài về nhà cung cấp lớp triển khai. Không cần ràng buộc trong Mô-đun ràng buộc trong trường hợp như vậy. Xem ví dụ:

Thí dụ

Tạo một lớp java có tên là 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;
   }
}

Đầu ra

Biên dịch và chạy tệp, bạn sẽ thấy kết quả sau.

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

Tiêm là một quá trình tiêm phụ thuộc vào một đối tượng. Việc tiêm hàm tạo khá phổ biến. Trong quá trình này, phụ thuộc được đưa vào làm đối số cho hàm tạo. Xem ví dụ bên dưới.

Tạo một lớp java có tên là 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." );
   } 
}

Đầu ra

Biên dịch và chạy tệp, bạn sẽ thấy kết quả sau.

Inside checkSpelling.

Tiêm là một quá trình tiêm phụ thuộc vào một đối tượng. Phương thức tiêm được sử dụng để đặt đối tượng giá trị là phụ thuộc vào đối tượng. Xem ví dụ bên dưới.

Thí dụ

Tạo một lớp java có tên là 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); 
   }
}

Đầu ra

Biên dịch và chạy tệp, bạn sẽ thấy kết quả sau.

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

Tiêm là một quá trình tiêm phụ thuộc vào một đối tượng. Chèn trường được sử dụng để đặt đối tượng giá trị làm phụ thuộc vào trường của một đối tượng. Xem ví dụ bên dưới.

Thí dụ

Tạo một lớp java có tên là 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); 
   }
}

Đầu ra

Biên dịch và chạy tệp, bạn sẽ thấy kết quả sau.

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

Tiêm là một quá trình tiêm phụ thuộc vào một đối tượng. Tiêm tùy chọn có nghĩa là tiêm phụ thuộc nếu tồn tại. Phương pháp và trường tiêm có thể phụ thuộc tùy ý và phải có một số giá trị mặc định nếu không có sự phụ thuộc. Xem ví dụ bên dưới.

Thí dụ

Tạo một lớp java có tên là 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); 
   }
}

Đầu ra

Biên dịch và chạy tệp, bạn sẽ thấy kết quả sau.

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

Tiêm là một quá trình tiêm phụ thuộc vào một đối tượng. Phương thức và trường tiêm có thể được sử dụng để khởi tạo bằng cách sử dụng đối tượng thoát bằng phương thức injectionor.injectMembers () . Xem ví dụ bên dưới.

Thí dụ

Tạo một lớp java có tên là 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." );
   }
}

Biên dịch và chạy tệp, bạn sẽ thấy kết quả sau.

Inside checkSpelling.

Guice trả về một phiên bản mới mỗi khi nó cung cấp một giá trị làm hành vi mặc định của nó. Nó có thể được cấu hình thông qua phạm vi. Sau đây là các phạm vi mà Guice hỗ trợ:

  • @Singleton- Phiên bản duy nhất cho toàn bộ thời gian của ứng dụng. Đối tượng @Singleton cần phải là threadsafe.

  • @SessionScoped- Phiên bản duy nhất cho một phiên cụ thể của ứng dụng web. Đối tượng @SessionScoped cần phải là threadsafe.

  • @RequestScoped- Ví dụ duy nhất cho một yêu cầu cụ thể của ứng dụng web. Đối tượng @RequestScoped không cần phải là threadsafe.

Cách áp dụng phạm vi.

Sau đây là các cách áp dụng phạm vi.

Ở cấp độ lớp học

@Singleton
class SpellCheckerImpl implements SpellChecker {

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

Ở mức cấu hình

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

Ở cấp độ Phương pháp

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

Thí dụ

Hãy xem Phạm vi ở cấp độ lớp đang hoạt động.

Kết quả với @Singleton Annotation

Tạo một lớp java có tên là 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;
   }
}

Biên dịch và chạy tệp, bạn có thể thấy kết quả sau.

0.3055839187063575
0.3055839187063575

Kết quả không có chú thích @Singleton

Tạo một lớp java có tên là 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;
   }
}

Biên dịch và chạy tệp, bạn có thể thấy kết quả sau.

0.556007079571739
0.22095011760351602

Google Guice - AOP

Lập trình định hướng AOP, Aspect đòi hỏi phải chia logic chương trình thành các phần riêng biệt được gọi là cái gọi là mối quan tâm. Các chức năng trải dài nhiều điểm của một ứng dụng được gọi là mối quan tâm xuyên suốt và những mối quan tâm xuyên suốt này tách biệt về mặt khái niệm với logic nghiệp vụ của ứng dụng. Có nhiều ví dụ điển hình phổ biến về các khía cạnh như ghi nhật ký, kiểm toán, giao dịch khai báo, bảo mật, bộ nhớ đệm, v.v.

Đơn vị quan trọng của mô-đun trong OOP là lớp, trong khi trong AOP, đơn vị mô-đun là khía cạnh. Dependency Injection giúp bạn tách các đối tượng ứng dụng của mình khỏi nhau và AOP giúp bạn tách các mối quan tâm xuyên suốt khỏi các đối tượng mà chúng ảnh hưởng. AOP giống như các trình kích hoạt trong các ngôn ngữ lập trình như Perl, .NET, Java và các ngôn ngữ khác. Guice cung cấp bộ chặn để chặn một ứng dụng. Ví dụ: khi một phương thức được thực thi, bạn có thể thêm chức năng bổ sung trước hoặc sau khi thực thi phương thức.

Các lớp quan trọng

  • Matcher- Matcher là một giao diện để chấp nhận hoặc từ chối một giá trị. Trong Guice AOP, chúng ta cần hai đối sánh: một để xác định các lớp nào tham gia và một cho các phương thức của các lớp đó.

  • MethodInterceptor- MethodInterceptors được thực thi khi một phương thức so khớp được gọi. Họ có thể kiểm tra cuộc gọi: phương thức, các đối số của nó và cá thể nhận. Chúng ta có thể thực hiện logic xuyên suốt và sau đó ủy quyền cho phương thức cơ bản. Cuối cùng, chúng tôi có thể kiểm tra giá trị trả về hoặc ngoại lệ và trả về.

Thí dụ

Tạo một lớp java có tên là 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;
   }
}

Biên dịch và chạy tệp, bạn có thể thấy kết quả sau.

Before checkSpelling
Inside checkSpelling.
After checkSpelling