Jonas Bonér bio photo

Jonas Bonér

Present.
Entrepreneur.
Hacker.
Public Speaker.
Powder Skier.
Perpetual Learner.
Jazz Fanatic.
Wannabee Musician.

Twitter LinkedIn Github
The Spring Framework is a very powerful library for J2EE development. It comes with an AOP implementation (based on proxies) that is in many cases sufficient in terms of what you need to do. However, there are many situations where you need a more full-blown AOP framework (such as AspectWerkz) to do the job.

On the other hand AspectWerkz (even though it has a decent API for configuration and management) could sometimes benefit from more finegrained and expressive configuration and life-cycle management, which is one thing that Spring does very well.

In short, it is sometimes beneficial to use these two frameworks together and I will now show you a first step on how you can make that happen.

AspectWerkz has a very open architecture in regards to instantiation, configuration and management of the aspects. Here I will show you how you can make use of this to take control over your aspects using Spring. (The concepts are the same for PicoContainer, HiveMind or a home-grown IoC implementation.)

In AspectWerkz instantiation, management and configuration of aspects is handled by an "aspect container" and to make it easier for users to provide their own custom implementation it provides the abstract org.codehaus.aspectwerkz.aspect.AbstractAspectContainer class which handles all the nitty-gritty details.

All we have to do is to extend the org.codehaus.aspectwerkz.aspect.AbstractAspectContainer class and implement the abstract Object createAspect() method.

So let us do that. Here is the implementation of our SpringAspectContainer:

public class SpringAspectContainer extends AbstractAspectContainer {

    public static final String SPRING_ASPECT_CONTAINER_CONFIG = "spring-bean-config.xml";

    /**
     * The Spring bean factory.
     */
    private XmlBeanFactory m_factory = null;

    /**
     * Creates a new aspect container strategy that uses the Spring framework to manage aspect instantiation and
     * configuaration.
     *
     * @param crossCuttingInfo the cross-cutting info
     */
    public SpringAspectContainer(final CrossCuttingInfo crossCuttingInfo) {
        super(crossCuttingInfo);
    }

    /**
     * Creates a new aspect instance.
     *
     * @return the new aspect instance
     */
    protected Object createAspect() {
        if (m_factory == null) {
            InputStream is = null;
            try {
                is = ClassLoader.getSystemResourceAsStream(SPRING_ASPECT_CONTAINER_CONFIG);
                m_factory = new XmlBeanFactory(is);
            } finally {
                try {
                    is.close();
                } catch (Throwable e) {
                    throw new WrappedRuntimeException(e);
                }
            }
        }

        // here we are letting Spring instantiate the aspect based on its name

        // (the m_infoPrototype field is the CrossCuttingInfo instance passed to the base class)

        return m_factory.getBean(m_infoPrototype.getAspectDefinition().getName());
    }
}

This is all that is needed implementation wise. Now we only have to define which aspects should be managed by our new container and configure the aspect in the Spring bean config file.

To tell the AspectWerkz system that we want to deploy a specific aspect in our custom aspect container we have to specify that in the regular aop.xml file like this:

<aspect class="some.package.MyAspect" container="some.other.package.SpringAspectContainer">
    ...
</aspect>

For details on the aop.xml file (what it is, how it is used etc.) see the online documentation.

To configure the aspect we just configure it like any other Spring bean class:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    <bean id="some.package.MyAspect"
          class="some.package.MyAspect"
          singleton="false"
          init-method="intialize">
        <property name="someProperty">
            ...
        </property>
        ...
    </bean>
    ...
</beans>

For details on how to define your bean classes see the Spring documentation. But here are some explainations:

  • id - specifies the name of the aspect if a custom name is define you that else use the class name of the aspect (which is the default name). Mandatory.
  • class - specifies the class name of the aspect. Mandatory.
  • singleton - specifies if the aspect will be instantiated using the prototype pattern or not. Mandatory.
  • init-method - the init-method is the method that you are using to initialize the aspect. This method will be called when all the properties have been set. Optional.
  • property - the metadata that you want to pass to the aspect (see the Spring documentation for details on how how to define properties). Optional.

Spring has great support for passing in expressive metadata. It for example allows you to pass in lists, maps of for example strings, primitives or custom objects, and arrange them pretty much as you like.

Here is a more interesting example on how you can configure an aspect using Spring's properties. This aspect implements role-based security and is part of the AWare aspect library:

<bean id="org.codehaus.aware.security.RoleBasedAccessProtocol"
    class="org.codehaus.aware.security.RoleBasedAccessProtocol"
    singleton="false"
    init-method="intialize">

    <property name="type">
        <value>JAAS</value>
    </property>

    <property name="roles">
        <list>
            <value>admin</value>
            <value>jboner</value>
        </list>
    </property>

    <property name="permissions">
        <list>
            <bean class="org.codehaus.aware.security.Permission">
                <property name="role">
                    <value>jboner</value>
                </property>
                <property name="className">
                    <value>org.codehaus.aware.security.SecurityHandlingTest</value>
                </property>
                <property name="methodName">
                    <value>authorizeMe1</value>
                </property>
            </bean>

           <bean class="org.codehaus.aware.security.Permission">
                <property name="role">
                    <value>jboner</value>
                </property>
                <property name="className">
                    <value>org.codehaus.aware.security.SecurityHandlingTest</value>
                </property>
                <property name="methodName">
                    <value>authorizeMe2</value>
                </property>
            </bean>
        </list>
    </property>

</bean>

You can find the code for the SpringAspectContainer along with many other reusable aspects in the AWare library. Which is a community-driven OSS library for reusable aspects for AspectWerkz.