Aspect Oriented Programming using Google Guice

Aspect Oriented Programming using Google Guice

Guice is compliant with the AOPAlliance’s specifications for aspect-oriented programming. We can implement the quintessential logging interceptor, which we will use to track message sending in our example, in only four steps.

Step 1 – Implement the AOPAlliance’s MethodInterceptor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MessageLogger implements MethodInterceptor {
 
    @Inject
    Logger logger;
 
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object[] objectArray = invocation.getArguments();
        for (Object object : objectArray) {
            logger.info("Sending message: " + object.toString());
        }
        return invocation.proceed();
    }
}

Step 2 – Define a plain java annotation:

1
2
3
4
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MessageSentLoggable {
}

Step 3 – Define a binding for a Matcher:

Matcher is a Guice class that we use do specify the components that our AOP annotation will apply to. In this case, we want the annotation to apply to implementations of CommunicationMode:
1
2
3
4
5
6
7
8
9
10
11
public class AOPModule extends AbstractModule {
 
    @Override
    protected void configure() {
        bindInterceptor(
            Matchers.any(),
            Matchers.annotatedWith(MessageSentLoggable.class),
            new MessageLogger()
        );
    }
}
We have specified a Matcher here that will apply our MessageLogger interceptor to any class, that has the MessageSentLoggable annotation applied to its methods.

Step 4 – Apply our annotation to our CommunicationMode and load our Module

1
2
3
4
5
6
7
8
9
10
11
@Override
@MessageSentLoggable
public boolean sendMessage(String message) {
    logger.info("SMS message sent");
    return true;
}
 
public static void main(String[] args) {
    Injector injector = Guice.createInjector(new BasicModule(), new AOPModule());
    Communication comms = injector.getInstance(Communication.class);
}

Comments

Popular posts from this blog

WMI Static Port configuration

Optimizing your JVM for Best Performance

How do I disable FOREIGN KEY checking for the time of database schema migration?