Inject a Dependency using AOP
Another interesting place where field annotations and AOP can be used is with dependency injection. Dependency injection is about objects declaring what information, configuration, or service references they need, and having the runtime automagically inject those dependencies rather than having your code do explicit lookups on a registry service. In J2EE-land, getting access to a javax.transaction.TransactionManager service is not standardized and is actually different per vendor implementation. Many framework developers need to use the TransactionManager to implement custom transactional services. The use of AOP with field annotations is a great way to provide this dependency injection and to abstract away the details of how a TransactionManager is referenced by components that need it. Let's define an aspect that will inject a reference to a TransactionManager into the value of a field. First, we must again define our annotation. package org.jboss.aspects; import java.lang.annotation.ElementType; import java.lang.annotation.Target; @Target({ElementType.FIELD}) public @interface Inject {} Next we will define the aspect class that will encapsulate the resolving of the TransactionManager. This aspect will be specific to the JBoss application server, but you could define different implementations per vendor. package org.jboss.aspects; import org.jboss.aop.joinpoint.*; import java.lang.reflect.Field; import javax.transaction.TransactionManager; import org.jboss.tm.TxManager; public InjectTMAspect { private TransactionManager tm = TxManager.getInstance(); public Object access(FieldReadInvocation invocation) throws Throwable { return tm; } public Object access(FieldWriteInvocation invocation) throws Throwable { throw new RuntimeException( "Setting an @Injected variable is illegal"); } } Finally, we have to define the XML binding that will trigger the application of the InjectTMAspect when the @Inject tag is applied to a field. The pointcut expression basically states that for any field of type TransactionManager and tagged as @Inject, apply the InjectTMAspect. Now that the annotation, aspect class, and XML binding have been defined, we can use it within our code. import javax.transaction.TransactionManager; import org.jboss.aspects.Inject; public class MyTransactionalCache { @Inject private TransactionManager tm; ... }