# AOP Configuration and Usage

When writing a new version of the Kernel, there was always a need for simple usage of advanced AOP features in the Kernel itself. With version 2.0.0 of the Microcontainer there is an elegant way of binding your aspect to wired POJOs, using all the advantages of full dependency state machine. Meaning that even aspects behave as installed services, having full lifecycle and dependency support in the Microcontainer. And it's all a matter of configuration if you want to use an aspectized Microcontainer or just plain POJO behaviour. To find out more about JBoss AOP, please see the JBoss AOP documentation.

## Configuration

To leverage the JBoss AOP integration in the Microcontainer you need to make sure that `jboss-aop-mc-int.jar` is available on the classpath. The Microcontainer will decide how whether to use AOP depending on if classes from this jar are present.

To use the AOP integration we must include the `AspectManager` bean. in our configuration. It is included as follows

    <?xml version="1.0" encoding="UTF-8"?>
    <deployment xmlns="urn:jboss:bean-deployer:2.0">
       <bean name="AspectManager" class="org.jboss.aop.AspectManager">
          <constructor
             factoryClass="org.jboss.aop.AspectManager"
             factoryMethod="instance"/>
       </bean>

       <!-- declare beans and aspects -->
    </deployment>

## Using Aspects

We can apply aspects to any beans we like. This can either be done by using already woven classes (loadtime or compile-time weaving). If the bean class is not already woven, but should have aspects applied to it, a proxy will be generated. If the class is not woven, field level aspects will not get triggered, you will only get constructor and method-level interception.

    <?xml version="1.0" encoding="UTF-8"?>
    <deployment xmlns="urn:jboss:bean-deployer:2.0">
       <bean name="AspectManager" class="org.jboss.aop.AspectManager">
          <constructor
             factoryClass="org.jboss.aop.AspectManager"
             factoryMethod="instance"/>
       </bean>

       <aop:aspect xmlns:aop="urn:jboss:aop-beans:1.0"
                   name="FooAdvice"
                   class="org.jboss.test.microcontainer.support.TestAspect">
       </aop:aspect>

       <aop:bind xmlns:aop="urn:jboss:aop-beans:1.0"
                   pointcut="execution(* *.SimpleBeanImpl->someMethod(..))">
          <advice aspect="FooAdvice" advice="foo"/>
       </aop:bind>

       <bean
          name="Intercepted"
          class="org.jboss.test.microcontainer.support.SimpleBeanImpl"/>
       <!-- declare beans and aspects -->
    </deployment>

    import org.jboss.aop.joinpoint.Invocation;

    public class TestAspect
    {
       public static boolean fooCalled;
       public static boolean barCalled;
       boolean shouldInvoke;

       public Object foo(Invocation inv) throws Throwable
       {
          System.out.println("--- foo");
          return inv.invokeNext();
       }
    }

In the above example, the elements in the `aop` namespace follow the same format as in a `-aop.xml`. Please see the JBoss AOP documentation for more details.

Whenever we call the method `someMethod()` in the `Intercepted` bean, we will get intercepted by the `FooAdvice` bean's `foo()` method. The aspect methods must have the signature shown. The JBoss AOP documentation contains more information about advice methods, and the pointcut expressions used to pick out methods/constructors/fields that should have aspects applied.

## AOP Lifecycle callbacks

We can also aspectize the installs and uninstalls of a bean. The following snippet shows a AOP lifecycle callback handler that gets triggered once `StartBean` enters the `start` state upon deployment, and when it leaves the `start` state upon undeployment.

    <?xml version="1.0" encoding="UTF-8"?>
    <deployment xmlns="urn:jboss:bean-deployer:2.0">
       <bean name="AspectManager" class="org.jboss.aop.AspectManager">
          <constructor
             factoryClass="org.jboss.aop.AspectManager"
             factoryMethod="instance"/>
       </bean>

       <aop:lifecycle-start xmlns:aop="urn:jboss:aop-beans:1.0"
                   name="InstallAdvice"
                   class="org.jboss.test.microcontainer.support.LifecycleCallback"
                   classes="@org.jboss.test.microcontainer.support.Start">
       </aop:lifecycle-start>

       <bean name="StartBean"
          class="org.jboss.test.microcontainer.support.SimpleBeanImpl">
          <annotation>@org.jboss.test.microcontainer.support.Start</annotation>
       </bean>

    </deployment>

    import org.jboss.dependency.spi.ControllerContext;

    public class LifecycleCallback{
       public void install(ControllerContext ctx){
          System.out.println("Bean " + ctx.getName() + " is being installed";
       }

       public void install(ControllerContext ctx){
          System.out.println("Bean " + ctx.getName() + " is being uninstalled";
       }
    }

The `install` and `uninstall` methods are required, and must have the signature shown. The names of these methods can be overridden by passing in the `installMethod` and `uninstallMethod` attributes as part of the `aop:lifecycle-start` tag.

We can also intercept the install/uninstall upon entering/leaving other states, by substituting `aop:lifecycle-start` with one of the following.

- `aop:lifecycle-configure` - Triggered when the target beans enter/leave the `configure` lifecycle state upon deployment/undeployment
- `aop:lifecycle-create` - Triggered when the target beans enter/leave the `create` lifecycle state upon deployment/undeployment
- `aop:lifecycle-describe` - Triggered when the target beans enter/leave the `describe` lifecycle state upon deployment/undeployment
- `aop:lifecycle-install` - Triggered when the target beans enter/leave the `install` lifecycle state upon deployment/undeployment
- `aop:lifecycle-instantiate` - Triggered when the target beans enter/leave the `instantiate` lifecycle state upon deployment/undeployment

## Aspect dependencies

Aspects and AOP lifecycle callbacks configured via the microcontainer can have dependencies just as normal beans can have. Beans which have these aspects applied inherit the aspect's dependencies.

    <?xml version="1.0" encoding="UTF-8"?>
    <deployment xmlns="urn:jboss:bean-deployer:2.0">
       <bean name="AspectManager" class="org.jboss.aop.AspectManager">
          <constructor
             factoryClass="org.jboss.aop.AspectManager"
             factoryMethod="instance"/>
       </bean>

       <aop:lifecycle-configure xmlns:aop="urn:jboss:aop-beans:1.0"
                name="JMXAdvice"
                class="org.jboss.aop.microcontainer.aspects.jmx.JMXLifecycleCallback"
                classes="@org.jboss.aop.microcontainer.aspects.jmx.JMX">
          <property name="mbeanServer"><inject bean="MBeanServer"/></property>
       </aop:lifecycle-configure>

       <aop:aspect xmlns:aop="urn:jboss:aop-beans:1.0"
                name="TxAdvice"
                class="org.acme.aspects.TxAspect"
          <property name="txManager"><inject bean="TxManager"/></property>
       </aop:aspect>

       <aop:bind xmlns:aop="urn:jboss:aop-beans:1.0"
                pointcut="execution(* *->@org.acme.Tx(..))">
          <advice aspect="TxAdvice" name="invoke"/>
       </aop:bind>

       <bean name="BeanWithAspects"
          class="org.jboss.test.microcontainer.support.SimpleBeanImpl">
          <annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX</annotation>
          <annotation>@org.acme.Tx</annotation>
       </bean>

       <bean name="PlainBean"
          class="org.jboss.test.microcontainer.support.SimpleBeanImpl">
       </bean>

    </deployment>

`JmxAdvice` depends on a bean called `MBeanServer` having been deployed, and `TxAdvice` depends on a bean called `TxManager` having been deployed. `BeanWithAspects` has been annotated with both `@JMX` and `@Tx`. Using this configuration, `BeanWithAspects` gets both `JMXAdvice` and `TxAdvice` applied. `BeanWithAspects` inherits the dependencies of all applied aspects and AOP lifecycle callbacks, so it cannot be started until `JMXAdvice` and `TxAdvice` have their dependencies satisfied. `PlainBean` on the other hand, has no aspects applied, and so has no extra dependencies from the AOP layer.