All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nanocontainer.aop..svn.text-base.package.html.svn-base Maven / Gradle / Ivy






Lets you configure aspects on components in a {@link org.picocontainer.PicoContainer}. Two kinds of advice are supported, interceptors and mixins. An interceptor is invoked around method calls. Interceptors implement the org.aopalliance.interceptor.MethodInterceptor interface. Mixins allow you to add new methods and behavior to an existing object. You can think of them as a way of dynamically providing multiple inheritance in java. Mixins can be any kind of object; they are not required to extend or implement anything. You can configure aspects in Java, or using groovy. Advice can be configured for all components in a container, using pointcuts, or advice can be applied to just one component. Advice objects may themselves have dependencies on other components, supplied by the container. Currently, dynaop is used to apply the aspects. Other backends may be supported in the future.

Configuring Aspects

For the following examples, we'll use the following logging interceptor:
    public class LoggingInterceptor implements org.aopalliance.intercept.MethodInterceptor {
        public Object invoke(MethodInvocation invocation) throws Throwable {
            System.out.println("start");
            Object result = invocation.proceed();
            System.out.println("end");
            return result;
        }
    }
We'll also assume that we have a Dao interface, with an implementation class DaoImpl.

Java Configuration

The primary interface for configuring aspects in Java is {@link org.nanocontainer.aop.AspectablePicoContainer}. To create one you need a {@link org.nanocontainer.aop.AspectablePicoContainerFactory}. The following example applies our logging interceptor to all methods of all instances of Dao in the container:
    AspectablePicoContainerFactory containerFactory = new DynaopAspectablePicoContainerFactory();
    AspectablePicoContainer pico = containerFactory.createContainer();
    PointcutsFactory cuts = pico.getPointcutsFactory();
    
    LoggingInterceptor logger = new LoggingInterceptor();
    pico.registerComponentImplementation(Dao.class, DaoImpl.class);
    pico.registerInterceptor(cuts.instancesOf(Dao.class), cuts.allMethods(), logger);

    Dao dao = (Dao) pico.getComponentInstance(Dao.class);
    dao.aMethod(); // will print 'startend'

If we wanted to apply our interceptor to just one component, we could do the following:

    pico.registerComponentImplementation("myDao", DaoImpl.class);
    pico.registerInterceptor(cuts.component("myDao"), cuts.allMethods(), logger);
Note that components and aspects can be registered in any order. An aspect can be registered before the component it applies to. In the example above, we could have reversed the two lines and registered the interceptor before the component.

Container Supplied Advice

Advice objects may themselves be components in the PicoContainer, with dependencies on other components. Let's revise our LoggingInterceptor to have a dependency on a log object of some sort. For simplicity, we'll just use a StringBuffer as our logger (in real life it might be a log4j or a commons logging object of some sort):
    public class LoggingInterceptor {
        private final StringBuffer log;
        
        public LoggingInterceptor(StringBuffer log) {
            this.log = log;
        }
        
        public Object invoke(MethodInvocation invocation) throws Throwable {
            log.append("start");
            Object result = invocation.proceed();
            log.append("end");
            return result;
        }
    }
With this in place, we could then register our LoggingInterceptor and apply it to a component as follows:
    // register dependency of LoggingInterceptor:
    pico.registerComponentInstance("log", StringBuffer.log); 
    
    pico.registerComponentImplementation("logger", LoggingInterceptor.class);
    pico.registerComponentImplementation("myDao", DaoImpl.class);

    // you can specify the component key of the advice object:
    pico.registerInterceptor(cuts.component("myDao"), cuts.allMethods(), "logger");
Pico will supply the StringBuffer "log" component to the constructor of the LoggingInterceptor.

Mixins are a special case. While you can register a mixin as an explicit component in the container, you usually don't want to. Applying the same mixin instance as advice to multiple components would in effect mean that multiple components would share the same base class object - sharing the same instances variables, etc. This is usually not a good thing. However, you may specify a mixin class that has dependencies on components in the container. The container will instantiate a new mixin object for each component that it applies the mixin to, but will satisfy any dependencies the mixin has from components in the container, using constructor injection.

Pointcuts

Notice the use of the {@link org.nanocontainer.aop.PointcutsFactory}, cuts, in the first example. This interface provides methods for producing pointcuts that match one class or method, or that match the class, method or component name against a regular expressionm, pointcuts that pick all instances of a given class, or all classes in a given package, etc. You are not limited to the pointcuts produced by PointcutsFactory however. Any pointcut that implements one of the interfaces {@link org.nanocontainer.aop.ComponentPointcut}, {@link org.nanocontainer.aop.ClassPointcut}, {@link org.nanocontainer.aop.MethodPointcut} will work. Class pointcuts match against the component's class. Component pointcuts match against the component key. Method pointcuts match against the method being invoked. Method pointcuts only apply to interceptor advice; they are not used for mixins.

Groovy Configuration

To configure aspects using groovy, use {@link org.nanocontainer.aop.script.groovy.DynaopNanoContainerBuilder}.

Limitations

Components that have aspects applied to them must implement an interface. Advice is not applied to components registered via registerComponentInstance, or for components supplied via a custom ComponentAdapter.




© 2015 - 2025 Weber Informatics LLC | Privacy Policy