Concepts

Spring's slicing model allows slices to be reused regardless of advice types. You can target different types of tips using the same slice.

Theorg.springframework.aop.Pointcut interface is the central interface used to target advice to specific classes and methods. Below is the complete interface:

public interface Pointcut {
    ClassFilter getClassFilter();
    MethodMatcher getMethodMatcher();
}

Splitting the Pointcut interface into two parts allows you to reuse parts of the classes and methods being matched, as well as perform fine-grained composition operations (such as "joining" with another method matcher).

The ClassFilter interface is used to restrict the slice to a specified set of target classes. If the matches() method always returns true, then all target classes are matched. The following listing shows the definition of the ClassFilter interface:

public interface ClassFilter {
    boolean matches(Class clazz);
}

The MethodMatcher interface is usually more important. Below is the complete interface:

public interface MethodMatcher {
    boolean matches(Method m, Class<?> targetClass);
    boolean isRuntime();
    boolean matches(Method m, Class<?> targetClass, Object... args);
}

The matches(Method, Class) method is used to check whether a given slice matches a given method in the target class. This calculation can be done when creating an AOP proxy to avoid having to perform a check on every method call. If the matches method with two arguments returns true for a given method, and the isRuntime() method returns true for a MethodMatcher, then the match method with three arguments will be called on every method call. This allows the slice to look at the arguments passed to the method call just before the target advice starts executing.

Most MethodMatcher implementations are static, meaning their isRuntime() method returns false. In this case, the matches method with three arguments is never called.

If possible, try to make the slices static by allowing the AOP framework to cache the slice calculation results when creating the AOP proxy.

Operations on slices

Spring supports operations (particularly union and intersection) on slices.

Union means methods that are the same as any of the slices. Intersection means methods that match both slices. Merging is usually a more practical operation. You can compose slices using static methods of the org.springframework.aop.support.Pointcuts class or using the ComposablePointcut class from the same package. However, using slice expressions from AspectJ is usually a simpler approach.

AspectJ Expression Slicers

As of version 2.0, the most important slice type used by Spring is org.springframework.aop.aspectj.AspectJExpressionPointcut. This is a slicer that uses the library provided by AspectJ to parse the slice expression string from AspectJ.

For a discussion of supported slice primitives from AspectJ, see previous chapter.

Convenient implementation of slices

Spring provides several convenient slicing implementations. Some of them can be used directly; others are designed to build subclasses in application-specific slices.

Static cuts

Static slices are based on the method and target class and cannot take method arguments into account. For most use cases, static slices are sufficient—and best. Spring can only evaluate a static slice once if the method is called for the first time. After this, there is no need to recalculate the slice every time the method is called.

The rest of this section describes some of the static slicing implementations that are included with Spring.

Regular Expression Cuts

One obvious way to define static slices is with regular expressions. Several AOP frameworks besides Spring allow this to happen. org.springframework.aop.support.JdkRegexpMethodPointcut is a generic regular expression cut that uses the JDK's regular expression support.

Using the JdkRegexpMethodPointcut class, you can specify a list of template strings. If any of them match, the slice will take the value true. (As a consequence, the resulting slice will actually be a union of the specified patterns).

The following example shows how to use

<bean id="settersAndAbsquatulatePointcut"
        class="org.springframework.aop.support.JdkRegexpMethodPointcut">
    <property name="patterns">
        <list>
            <value>.*set.*</value>
            <value>.*absquatulate</value>
        </list>
    </property>
</bean>

Spring provides a convenient RegexpMethodPointcutAdvisor class that allows you to also reference Advice (remember that Advice can be an "intercept" advice, an "advice" before", advice "throwing an exception" and others). Behind the scenes, Spring uses JdkRegexpMethodPointcut. Using RegexpMethodPointcutAdvisor simplifies linking because a single bean encapsulates both the cut and the advice, as shown in the following example:

<bean id="settersAndAbsquatulateAdvisor"
        class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
    <property name="advice">
        <ref bean="beanNameOfAopAllianceInterceptor"/>
    </property>
    <property name="patterns">
        <list>
            <value>.*set.*</value>
            <value>.*absquatulate</value>
        </list>
    </property>
</bean>

You can use RegexpMethodPointcutAdvisor with any Advice type.

Attribute-driven slices

An important type of static slice is the metadata-driven slice. This uses the values of metadata attributes (usually source-level metadata).

Dynamic slices

Calculating dynamic slices is a more resource-intensive task. These slices take into account method arguments as well as static information. This means that they must be evaluated each time the method is called and that the result cannot be cached because the arguments will change.

The main example is the control flow slice.

Control flow slices

Spring's control flow pointcuts are conceptually similar to AspectJ's cflow slices, although not as efficient. (There is currently no way to specify that a slice goes below a join point that coincides with another slice.) The control flow slice matches the current call stack. For example, it might fire if the connection point was called by a method from the com.mycompany.web package or the SomeCaller class. Control flow slices are specified using the org.springframework.aop.support.ControlFlowPointcut class.

Control flow slices are significantly more expensive to compute at runtime than even other dynamic slices. In Java 1.4, the cost is approximately five times higher than for other dynamic slicers.

Slice superclasses

Spring provides practical slicer superclasses (parent classes) that can help you implement your own slicers.

Java
class TestStaticPointcut extends StaticMethodMatcherPointcut {
    public boolean matches(Method m, Class targetClass) {
        // returns true if specially specified criteria match
    }
}
Kotlin
class TestStaticPointcut : StaticMethodMatcherPointcut() {
    override fun matches(method: Method, targetClass: Class<*>): Boolean {
        // returns true if specially specified criteria match
    }
}

There are also superclasses for dynamic slicers. You can use special cuts with any type of tips.

Special cuts

Because slices in Spring AOP are Java classes and not language functions (as in AspectJ), you can declare custom slices, either static or dynamic. Special slices in Spring can be arbitrarily complex. However, it is recommended to use the AspectJ slicing expression language if possible.

Later versions of Spring may provide support for "semantic slicing" as proposed in JAC - for example, "any methods that modify instance variables in the target object."