dynaop manual

Aspects

In AOP, aspects map advice to pointcuts. Declaring an aspect in dynaop is a simple matter of a method invocation. The dynaop script imports the methods from Aspects and overloads them to support the pointcut shortcuts mentioned in the previous section. All advice is lazily instantiated; the proxy does not create interceptor or mixin instances for a given method until that method is invoked.

Define aspects by invoking these methods. Each method accepts the pointcuts first and the advice definition second. The class pointcuts pick target classes. The method interception aspects use the method pointcut to pick methods in the target class as well as methods from interfaces added by other aspects; method pointcuts match against all of the methods in the final proxy as opposed to just those that have been added so far. The framework applies interception advice in the order of declaration.

Singleton Interceptor

This aspect binds a single interceptor instance. The interceptor instance may be shared by multiple proxies.

This aspect supports ProxyAware interface.

Usage:
interceptor(ClassPointcut, MethodPointcut, Interceptor);

Example:
interceptor(List.class, ALL_METHODS, new TraceInterceptor());

Per-Proxy Interceptor

This aspect creates a new instance of the given interceptor type for each proxy instance using the interceptor class's default constructor.

The Closure initializer is a command object that accepts one argument (the interceptor instance in this case). If an initializer is specified, the framework will execute it against the interceptor instance after creation and before use by the proxy. This can be used to set properties from the configuration script.

This aspect supports ProxyAware interface. The framework calls ProxyAware.setProxy() before invoking initializer.

Usage:
interceptor(ClassPointcut, MethodPointcut, Class interceptorClass[, 
  Closure initializer]);

Example:
interceptor(List.class, ALL_METHODS, TraceInterceptor.class, new Closure() {
  execute(interceptor) {
    interceptor.level = "DEBUG";
    interceptor.name = "List Trace";
  }
});

Custom Interceptor Factory

You can specify a custom InterceptorFactory to support alternate modes of interceptor lookup or construction.

Usage:
interceptor(ClassPointcut, MethodPointcut, InterceptorFactory);

Example:
interceptor(List.class, ALL_METHODS, new PersistentInterceptorFactory());

Mixin Introduction

This aspect attaches a mixin instance to classes picked by the class pointcut. A mixin is a plain Java object that implements the specified interfaces. If you don't specify interfaces for the mixin to implement, the aspect uses all of the interfaces implemented by the mixin class.

This aspect supports ProxyAware interface. The framework calls ProxyAware.setProxy() before invoking the initializer.

Usage:
mixin(ClassPointcut[, Class[] interfaces], Class mixinClass[, Closure initializer]);

Example:
mixin(List.class, SubjectMixin.class);

Custom Mixin Introduction Factory

This aspect manufactures mixins using a custom MixinFactory. This can be used for mixins without a default constructors, to implement a mixin using another proxy, to load mixin instances from a persistent store or over a network, etc.

Usage:
mixin(ClassPointcut, Class[] interfaces, MixinFactory);

Example:
mixin(List.class, new Class[] { Subject.class }, new SubjectMixinFactory());

Interfaces

This aspect adds interfaces sans implementation to classes picked by the class pointcut. Use this aspect when the interface's implementation is already specified by an interceptor or a mixin.

This can be used to add aggregated helper interfaces (i.e. an interface that extends all of the interfaces that will be added) to help reduce the need for casting.

Usage:
interfaces(ClassPointcut, Class[] interfaces);

Example:
interfaces(List.class, new Class[] { ListProxy.class });