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 trình so khớp: 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;
   }
}

Đầu ra

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