Google Guice - AOP
AOP, programação orientada a Aspectos envolve quebrar a lógica do programa em partes distintas chamadas de preocupações. As funções que abrangem vários pontos de um aplicativo são chamadas de interesses transversais e esses interesses transversais são conceitualmente separados da lógica de negócios do aplicativo. Existem vários bons exemplos comuns de aspectos como registro, auditoria, transações declarativas, segurança, armazenamento em cache, etc.
A unidade principal de modularidade em OOP é a classe, enquanto em AOP a unidade de modularidade é o aspecto. A injeção de dependência ajuda a desacoplar seus objetos de aplicativo uns dos outros e o AOP ajuda a desacoplar interesses transversais dos objetos que eles afetam. AOP é como gatilhos em linguagens de programação como Perl, .NET, Java e outras. O Guice fornece interceptores para interceptar um aplicativo. Por exemplo, quando um método é executado, você pode adicionar funcionalidade extra antes ou depois da execução do método.
Aulas importantes
Matcher- Matcher é uma interface para aceitar ou rejeitar um valor. No Guice AOP, precisamos de dois matchers: um para definir quais classes participam e outro para os métodos dessas classes.
MethodInterceptor- MethodInterceptors são executados quando um método de correspondência é chamado. Eles podem inspecionar a chamada: o método, seus argumentos e a instância de recebimento. Podemos executar lógica cruzada e então delegar ao método subjacente. Finalmente, podemos inspecionar o valor de retorno ou exceção e retornar.
Exemplo
Crie uma classe java chamada 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;
}
}
Resultado
Compile e execute o arquivo, você verá a seguinte saída.
Before checkSpelling
Inside checkSpelling.
After checkSpelling