GP Coder

Trang chia sẻ kiến thức lập trình Java

  • Java Core
    • Basic Java
    • OOP
    • Exception Handling
    • Multi-Thread
    • Java I/O
    • Networking
    • Reflection
    • Collection
    • Java 8
  • Design pattern
    • Creational Pattern
    • Structuaral Pattern
    • Behavior Pattern
  • Web Service
    • SOAP
    • REST
  • JPA
  • Java library
    • Report
    • Json
    • Unit Test
  • Message Queue
    • ActiveMQ
    • RabbitMQ
  • All
Trang chủ Design pattern Creational Pattern Giới thiệu Google Guice – Aspect Oriented Programming (AOP)

Giới thiệu Google Guice – Aspect Oriented Programming (AOP)

Đăng vào 14/02/2019 Được đăng bởi GP Coder 3345 Lượt xem

Trong các bài trước, tôi đã giới thiệu với các bạn Aspect Oriented Programming (AOP) và cách tự xây dựng một AOP Framework với JDK Proxy. Trong bài này, chúng ta sẽ cùng tìm hiểu cách sử dụng AOP với thư viện Google Guice.

Nội dung

  • 1 Giới thiệu Google Guice AOP
  • 2 Ví dụ sử dụng AOP với thư viện Google Guice

Giới thiệu Google Guice AOP

Ngoài việc hỗ trợ mạnh mẽ về Dependency Injection (DI), nhiều loại Binding, Injection và Scope. Google còn hỗ trợ về AOP.

Guice AOP tuân thủ các đặc tả về cài đặt của  AOP Alliance cho lập trình hướng khía cạnh (AOP). Điều này cho phép sử dụng cùng một Interceptor trên nhiều Framework khác nhau.

Hai class quan trọng của Guice AOP:

  • Matcher : là một interface dùng để chấp nhận hoặc từ chối một giá trị. Trong Guice AOP, chúng ta cần hai matcher: một để xác định lớp nào tham gia và một để xác định các phương thức của các lớp đó.
  • MethodInterceptor : phương thức này được thực thi khi một phương thức thõa mãn matcher được gọi. Chúng ta có thể lấy được thông tin về phương thức gọi, các đối số và instance nhận được. Chúng ta có thể thực hiện logic cross-cutting concern và sau đó ủy quyền lại cho phương thức cơ bản (core concern). Cuối cùng, chúng ta có thể kiểm tra giá trị trả về hoặc throw ngoại lệ và return kết quả.

Ví dụ sử dụng AOP với thư viện Google Guice

Để sử dụng AOP với Guice, đơn giản chỉ thực hiện theo một vài bước sau:

  • Tạo một class implements lại phương thức invoke() của interface MethodInterceptor : dùng để cài đặt logic cross-cutting concern – các xử lý trước và sau khi logic xử lý chính được gọi (core concerns).
  • Tạo một annotation : dùng để đánh dấu phương thức nào sẽ được áp dụng logic được cài đặt với MethodInterceptor. Nếu không thích sử dụng Annotation, bạn thể có thể sử config Matcher trên package, sub-package, …
  • Cấu hình Binding cho Matcher trong file Module của Guice.
  • Đánh dấu Annotation đã tạo ở trên cho các phương thức cần áp dụng logic cross-cutting concern.

Chúng ta sẽ sử dụng lại ví dụ tự xây dựng một AOP Framework với JDK Proxy ở bài viết trước. Chương trình của chúng ta được viết lại bằng cách sử dụng Google Guice AOP như sau:

Account.java


package com.gpcoder.patterns.creational.googleguice.aop.account;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class Account {

	private String owner;
	private String currency;
	private int balance;
}

AccountService.java


package com.gpcoder.patterns.creational.googleguice.aop.account;

public interface AccountService {

	void addAccount(Account account);

	void removeAccount(Account account);
	
	int getSize();
}

AccountServiceImpl.java


package com.gpcoder.patterns.creational.googleguice.aop.account;

import java.util.ArrayList;
import java.util.List;

import com.gpcoder.patterns.creational.googleguice.aop.handler.Loggable;

public class AccountServiceImpl implements AccountService {

	private List<Account> accounts = new ArrayList<>();

	@Loggable
	@Override
	public void addAccount(Account account) {
		System.out.println("addAccount: " + account);
		accounts.add(account);
	}

	@Loggable
	@Override
	public void removeAccount(Account account) {
		System.out.println("removeAccount: " + account);
		accounts.remove(account);
	}

	@Loggable
	@Override
	public int getSize() {
		System.out.println("getSize: " + accounts.size());
		return accounts.size();
	}
}

LoggingInterceptor.java


package com.gpcoder.patterns.creational.googleguice.aop.handler;

import java.util.logging.Logger;

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

import com.google.inject.Inject;

/**
 * Implement the AOP Alliance's MethodInterceptor
 */
public class LoggingInterceptor implements MethodInterceptor {

	@Inject
	private Logger logger;

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		logger.info("LoggingInterceptor");
		
		// Handle before
		System.out.println("Handling before actual method execution");
		
		// Inspect the call: the method, its arguments
		System.out.println("Gets the method being called: " + invocation.getMethod().getName());
		Object[] objectArray = invocation.getArguments();
		for (Object object : objectArray) {
			System.out.println("Get the arguments: " + object);
		}
		
		// Proceeds to the next interceptor in the chain. 
		Object result = invocation.proceed();
		
		// Handle after
		System.out.println("Handling after actual method execution");
		System.out.println("---");
		
		return result;
	}
}

BasicModule.java


package com.gpcoder.patterns.creational.googleguice.aop.handler;

import com.google.inject.AbstractModule;
import com.gpcoder.patterns.creational.googleguice.aop.account.AccountService;
import com.gpcoder.patterns.creational.googleguice.aop.account.AccountServiceImpl;

public class BasicModule extends AbstractModule {

	@Override
    protected void configure() {
		bind(AccountService.class).to(AccountServiceImpl.class);
	}
}

AOPModule.java


package com.gpcoder.patterns.creational.googleguice.aop.handler;

import com.google.inject.AbstractModule;
import com.google.inject.matcher.Matchers;

public class AOPModule extends AbstractModule {

	@Override
	protected void configure() {
		// Inject interceptor
		LoggingInterceptor loggingInterceptor = new LoggingInterceptor();
		requestInjection(loggingInterceptor);

		// Define a binding for a Matcher
		bindInterceptor(Matchers.any(), Matchers.annotatedWith(Loggable.class), loggingInterceptor);
	}
}

Loggable.java


package com.gpcoder.patterns.creational.googleguice.aop.handler;

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

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

AspectOrientedProgrammingInJdkExample.java


package com.gpcoder.patterns.creational.googleguice.aop;

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.gpcoder.patterns.creational.googleguice.aop.account.Account;
import com.gpcoder.patterns.creational.googleguice.aop.account.AccountService;
import com.gpcoder.patterns.creational.googleguice.aop.account.AccountServiceImpl;
import com.gpcoder.patterns.creational.googleguice.aop.handler.AOPModule;
import com.gpcoder.patterns.creational.googleguice.aop.handler.BasicModule;

/**
 * This class to verify an AOP example using Google Guice.
 */
public class AspectOrientedProgrammingWithGuice {

	public static void main(String[] args) {

		Injector injector = Guice.createInjector(new BasicModule(), new AOPModule());
		AccountService proxy = injector.getInstance(AccountServiceImpl.class);

		Account account = new Account("gpcoder", "USD", 100);
		proxy.addAccount(account);
		proxy.getSize();
		proxy.removeAccount(account);
		proxy.getSize();
	}
}

Output của chương trình:


Feb 12, 2019 9:25:04 PM com.gpcoder.patterns.creational.googleguice.aop.handler.LoggingInterceptor invoke
INFO: LoggingInterceptor
Handling before actual method execution
Gets the method being called: addAccount
Get the arguments: Account(owner=gpcoder, currency=USD, balance=100)
addAccount: Account(owner=gpcoder, currency=USD, balance=100)
Handling after actual method execution
---
Feb 12, 2019 9:25:04 PM com.gpcoder.patterns.creational.googleguice.aop.handler.LoggingInterceptor invoke
INFO: LoggingInterceptor
Handling before actual method execution
Gets the method being called: getSize
getSize: 1
Handling after actual method execution
---
Handling before actual method executionFeb 12, 2019 9:25:04 PM com.gpcoder.patterns.creational.googleguice.aop.handler.LoggingInterceptor invoke
INFO: LoggingInterceptor

Gets the method being called: removeAccount
Get the arguments: Account(owner=gpcoder, currency=USD, balance=100)
removeAccount: Account(owner=gpcoder, currency=USD, balance=100)
Handling after actual method execution
---
Feb 12, 2019 9:25:04 PM com.gpcoder.patterns.creational.googleguice.aop.handler.LoggingInterceptor invoke
INFO: LoggingInterceptor
Handling before actual method execution
Gets the method being called: getSize
getSize: 0
Handling after actual method execution
---

Tài liệu tham khảo:

    • https://github.com/google/guice/wiki/AOP
    • https://www.tutorialspoint.com/guice/guice_aop.htm
    • https://www.baeldung.com/guice
5.0
07
Nếu bạn thấy hay thì hãy chia sẻ bài viết cho mọi người nhé!

Shares

Chuyên mục: Creational Pattern, Design pattern, Java library Được gắn thẻ: AOP, Creational Design Pattern, Dependency Injection, Design pattern, Google Guice

Giới thiệu Aspect Oriented Programming (AOP)
Hướng dẫn Java Design Pattern – MVC

Có thể bạn muốn xem:

  • Giới thiệu Design Patterns (30/08/2018)
  • Tạo số và chuỗi ngẫu nhiên trong Java (15/09/2019)
  • Hướng dẫn Java Design Pattern – Memento (25/12/2018)
  • Hướng dẫn Java Design Pattern – Dependency Injection (28/01/2019)
  • Java Web Services – Jersey JAX-RS – REST và sử dụng REST API testing tools với Postman (10/06/2019)

Bình luận

bình luận

Tìm kiếm

Bài viết mới

  • Giới thiệu CloudAMQP – Một RabbitMQ server trên Cloud 02/10/2020
  • Kết nối RabbitMQ sử dụng Web STOMP Plugin 19/06/2020
  • Sử dụng publisher confirm trong RabbitMQ 16/06/2020
  • Sử dụng Dead Letter Exchange trong RabbitMQ 13/06/2020
  • Sử dụng Alternate Exchange trong RabbitMQ 10/06/2020

Xem nhiều

  • Hướng dẫn Java Design Pattern – Factory Method (65881 lượt xem)
  • Hướng dẫn Java Design Pattern – Singleton (64371 lượt xem)
  • Lập trình đa luồng trong Java (Java Multi-threading) (60597 lượt xem)
  • Giới thiệu Design Patterns (57266 lượt xem)
  • Giới thiệu về Stream API trong Java 8 (53776 lượt xem)

Nội dung bài viết

  • 1 Giới thiệu Google Guice AOP
  • 2 Ví dụ sử dụng AOP với thư viện Google Guice

Lưu trữ

Thẻ đánh dấu

Annotation Authentication Basic Java Behavior Pattern Collection Creational Design Pattern Cấu trúc điều khiển Database Dependency Injection Design pattern Eclipse Exception Executor Service Google Guice Gson Hibernate How to Interceptor IO Jackson Java 8 Java Core JDBC JDK Jersey JMS JPA json JUnit JWT Message Queue Mockito Multithreading OOP Performance PowerMockito RabbitMQ Reflection Report REST SOAP Structuaral Pattern Thread Pool Unit Test Webservice

Liên kết

  • Clean Code
  • JavaTpoint
  • Refactoring Guru
  • Source Making
  • TutorialsPoint
  • W3Schools Online Web Tutorials

Giới thiệu

GP Coder là trang web cá nhân, được thành lập với mục đích lưu trữ, chia sẽ kiến thức đã học và làm việc của tôi. Các bài viết trên trang này chủ yếu về ngôn ngữ Java và các công nghệ có liên quan đến Java như: Spring, JSF, Web Services, Unit Test, Hibernate, SQL, ...
Hi vọng góp được chút ít công sức cho sự phát triển cộng đồng Coder Việt.

Tìm kiếm các bài viết của GP Coder với Google Search

Liên hệ

Các bạn có thể liên hệ với tôi thông qua:
  • Trang liên hệ
  • Linkedin: gpcoder
  • Email: contact@gpcoder.com
  • Skype: ptgiang56it

Follow me

Copyright 2023 © GP Coder · All Rights Reserved · Giới thiệu · Chính sách · Điều khoản · Liên hệ ·

Share

Blogger
Delicious
Digg
Email
Facebook
Facebook messenger
Google
Hacker News
Line
LinkedIn
Mix
Odnoklassniki
PDF
Pinterest
Pocket
Print
Reddit
Renren
Short link
SMS
Skype
Telegram
Tumblr
Twitter
VKontakte
wechat
Weibo
WhatsApp
Xing
Yahoo! Mail

Copy short link

Copy link