Spring AOP within Pointcut Example

0

within is an AspectJ pointcut designator that helps narrow down the join point matches using type as the matching criteria. We can use it to define a pointcut that executes a method only when declared within a matching type.

Match Join Points within a Package

Suppose we want to build our pointcut expression based on all the method execution within the package com.javarticles. For the sake of example, we have defined two sub-packages within the main package com.javarticles.

  1. com.javarticles.serviceA
  2. com.javarticles.serviceB

First we will define the pointcut, in our case, we want to consider all the methods within the classes defined in package com.javarticles.

    @Pointcut("within(com.javarticles.*)")
    public void onAnyMethodInJavaArticles() {
    }

We will also define a pointcut expression to match all classes defined in package com.javarticles.serviceA.

    @Pointcut("within(com.javarticles.serviceA.*)")
    public void onAnyMethodInServiceA() {
    }

We will not define any pointcut expression for package com.javarticles.serviceB.

Here is the complete class containing the two pointcut expressions. As we move forward with each section, we will be adding more pointcut expressions to this class.

AopWithinPointcutBean:

package com.javarticles;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class AopWithinPointcutBean {    
    
    @Pointcut("within(com.javarticles.*)")
    public void onAnyMethodInJavaArticles() {
    }
    
    @Pointcut("within(com.javarticles.serviceA.*)")
    public void onAnyMethodInServiceA() {
    }
}

Next, we will use the declared pointcut to define the join point when the advice will be executed. In the below aspect annotated class, we have defined couple of @Before advice methods for each declared pointcut.

AopBeforeAdvice:

package com.javarticles;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class AopBeforeAdvice {
    
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethodInJavaArticles()")
    public void beforeAnyMethodInJavArticles() {
        System.out.println("before advice applied before invoking any method in package com.javarticles");
    } 

    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethodInServiceA()")
    public void beforeAnyMethodInServiceA() {
        System.out.println("before advice applied before invoking any method in package com.javarticles.serviceA");
    }        
}

Each package containsĀ a class.

com.javarticles.C:

package com.javarticles;

@EnableDiagnostics(recordEvent=true)
public class C {
    public void c1() {
        System.out.println("c1");
    }

    public void c2() {
        System.out.println("c2");
    }
}

com.javarticles.serviceA.A:

package com.javarticles.serviceA;

public class A {
    public void a1() {
        System.out.println("a1");
    }

    public void a2() {
        System.out.println("a2");
    }
}

com.javarticles.serviceB.B:

package com.javarticles.serviceB;

public class B {
    public void b1() {
        System.out.println("b1");
    }

    public void b2() {
        System.out.println("b2");
    }
}

We need to define all the beans in spring context container.

applicationContext.xml:

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

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
	
    <aop:aspectj-autoproxy proxy-target-class="true"/>
	<bean id="aopWithinPointcut" class="com.javarticles.AopWithinPointcutBean"/>
	<bean id="aopBeforeAdvices" class="com.javarticles.AopBeforeAdvice"/>
	<bean id="serviceA" class="com.javarticles.serviceA.A"/>
	<bean id="serviceB" class="com.javarticles.serviceB.B"/>
	<bean id="serviceC" class="com.javarticles.C"/>
</beans>

In our main class, we will simply load the spring context and call methods from each bean.

SpringAopPointcutExample:

package com.javarticles;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.javarticles.serviceA.A;
import com.javarticles.serviceB.B;

public class SpringAopPointcutExample {
    public static void main(String[] args) throws NoSuchMethodException, SecurityException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        try {
           A a = (A) context.getBean("serviceA");
           B b =  (B) context.getBean("serviceB");
           C c =  (C) context.getBean("serviceC");
           a.a1();
           a.a2();
           b.b1();
           b.b2();
           c.c1();
           c.c2();
        } finally {
            context.close();
        }
    }
}

As you can see, call to B.b1() and B.b2() didn’t result into any matching of join points as there is no pointcut defined for it.

Output:

before advice applied before invoking any method in package com.javarticles.serviceA
a1
before advice applied before invoking any method in package com.javarticles.serviceA
a2
b1
b2
before advice applied before invoking any method in package com.javarticles
c1
before advice applied before invoking any method in package com.javarticles
c2

Match Join Points within a Package and its Sub-packages

In our previous example, pointcut expression within(com.javarticles.*) included only the classes define in com.javarticles and not the sub-packages.

    
    @Pointcut("within(com.javarticles.*)")
    public void onAnyMethodInJavaArticles() {
    }

If we want to match the join points within a package and its subpackage then we will have to add one more dot before the wildcard.

    @Pointcut("within(com.javarticles..*)")
    public void onAnyMethod() {
    }

AopWithinPointcutBean:

package com.javarticles;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class AopWithinPointcutBean {    
    
    @Pointcut("within(com.javarticles.*)")
    public void onAnyMethodInJavaArticles() {
    }
    
    @Pointcut("within(com.javarticles.serviceA.*)")
    public void onAnyMethodInServiceA() {
    }
    
    @Pointcut("within(com.javarticles..*)")
    public void onAnyMethod() {
    }
}

We will define a @Before advice for the newly declared pointcut.

package com.javarticles;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class AopBeforeAdvice {
    
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethodInJavaArticles()")
    public void beforeAnyMethodInJavArticles() {
        System.out.println("before advice applied before invoking any method in package com.javarticles");
    }
    
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethodInServiceA()")
    public void beforeAnyMethodInServiceA() {
        System.out.println("before advice applied before invoking any method in package com.javarticles.serviceA");
    }    
    
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethod()")
    public void beforeAnyMethod() {
        System.out.println("before advice applied before invoking any method in package com.javarticles and sub-packages");
    } 
}

Now when we runĀ the main example again, we can see the @Before advice beforeAnyMethod sprang into action when we called B.b1() and B.b2().

Output:

before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invoking any method in package com.javarticles.serviceA
a1
before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invoking any method in package com.javarticles.serviceA
a2
before advice applied before invoking any method in package com.javarticles and sub-packages
b1
before advice applied before invoking any method in package com.javarticles and sub-packages
b2
before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invoking any method in package com.javarticles
c1
before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invoking any method in package com.javarticles
c2

Match Join Points within a Class

If you want the pointcut expression to match the method execution join points within a particular class then use the following:

    @Pointcut("within(com.javarticles.serviceA.TaskA)")
    public void onAnyMethodInTaskA() {
    }  

TaskA is a class defined in package com.javarticles.serviceA. It implements ITask interface. In our next section, we will see how to match join points based on an interface.

TaskA:

package com.javarticles.serviceA;

import com.javarticles.ITask;

public class TaskA implements ITask {
    public void doTaskA() {
        System.out.println("taskA");
    }
}

ITask:

package com.javarticles;

public interface ITask {

}

Declare pointcut for class TaskA.

AopWithinPointcutBean:

package com.javarticles;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class AopWithinPointcutBean {    
    
    @Pointcut("within(com.javarticles.*)")
    public void onAnyMethodInJavaArticles() {
    }
    
    @Pointcut("within(com.javarticles.serviceA.*)")
    public void onAnyMethodInServiceA() {
    }
    
    @Pointcut("within(com.javarticles..*)")
    public void onAnyMethod() {
    }
    
    @Pointcut("within(com.javarticles.serviceA.TaskA)")
    public void onAnyMethodInTaskA() {
    }    
}

Define a @Before advice onAnyMethodInTaskA() for the newly declared pointcut onAnyMethodInTaskA.

AopBeforeAdvice:

package com.javarticles;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class AopBeforeAdvice {
    
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethodInJavaArticles()")
    public void beforeAnyMethodInJavArticles() {
        System.out.println("before advice applied before invoking any method in package com.javarticles");
    }
    
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethodInServiceA()")
    public void beforeAnyMethodInServiceA() {
        System.out.println("before advice applied before invoking any method in package com.javarticles.serviceA");
    }    
    
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethod()")
    public void beforeAnyMethod() {
        System.out.println("before advice applied before invoking any method in package com.javarticles and sub-packages");
    } 
    
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethodInTaskA()")
    public void beforeAnyMethodInTaskA() {
        System.out.println("before advice applied before any method in TaskA");
    }        
}

Declare TaskA bean in the spring container.

applicationContext.xml:

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

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
	
    <aop:aspectj-autoproxy proxy-target-class="true"/>
	<bean id="aopWithinPointcut" class="com.javarticles.AopWithinPointcutBean"/>
	<bean id="aopBeforeAdvices" class="com.javarticles.AopBeforeAdvice"/>
	<bean id="serviceA" class="com.javarticles.serviceA.A"/>
	<bean id="serviceB" class="com.javarticles.serviceB.B"/>
	<bean id="serviceC" class="com.javarticles.C"/>
	<bean id="taskA" class="com.javarticles.serviceA.TaskA"/>
</beans>

In the main example, we will get TaskA bean and call taskA.doTaskA().

SpringAopPointcutExample:

package com.javarticles;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.javarticles.serviceA.A;
import com.javarticles.serviceA.TaskA;
import com.javarticles.serviceB.B;

public class SpringAopPointcutExample {
    public static void main(String[] args) throws NoSuchMethodException, SecurityException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        try {
           A a = (A) context.getBean("serviceA");
           B b =  (B) context.getBean("serviceB");
           C c =  (C) context.getBean("serviceC");
           TaskA taskA =  (TaskA) context.getBean("taskA");
           TaskB taskB =  (TaskB) context.getBean("taskB");
           a.a1();
           a.a2();
           b.b1();
           b.b2();
           c.c1();
           c.c2();
           taskA.doTaskA();
        } finally {
            context.close();
        }
    }
}

You can see from the output, the @Before advice beforeAnyMethodInTaskA() gets called along with other join point matches.

Output:

before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invoking any method in package com.javarticles.serviceA
a1
before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invoking any method in package com.javarticles.serviceA
a2
before advice applied before invoking any method in package com.javarticles and sub-packages
b1
before advice applied before invoking any method in package com.javarticles and sub-packages
b2
before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invoking any method in package com.javarticles
c1
before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invoking any method in package com.javarticles
c2
before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invoking any method in package com.javarticles.serviceA
before advice applied before any method in TaskA
taskA

Match Join Points within classes implementing a specific Interface

In case you want to match the method execution join points within all classes that implement a specific interface. In our example, we already have class TaskA that implements ITask. We will now create another class TaskB which too implements ITask.

TaskB:

package com.javarticles.serviceB;

import com.javarticles.ITask;

public class TaskB implements ITask {
    public void doTaskB() {
        System.out.println("taskB");
    }
}

In order to match the join points within classes that implement a specific interface, we need to use the following pointcut expression which ends with a plus symbol.

    @Pointcut("within(com.javarticles.ITask+)")
    public void onAnyMethodOnInterface() {
    }

Let’s add the above pointcut declaration to our class AopWithinPointcutBean.

AopWithinPointcutBean:

package com.javarticles;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class AopWithinPointcutBean {    
    
    @Pointcut("within(com.javarticles.*)")
    public void onAnyMethodInJavaArticles() {
    }
    
    @Pointcut("within(com.javarticles.serviceA.*)")
    public void onAnyMethodInServiceA() {
    }
    
    @Pointcut("within(com.javarticles..*)")
    public void onAnyMethod() {
    }
    
    @Pointcut("within(com.javarticles.serviceA.TaskA)")
    public void onAnyMethodInTaskA() {
    }
    
    @Pointcut("within(com.javarticles.ITask+)")
    public void onAnyMethodOnInterface() {
    }
}

We will also define a @Before advice.

AopBeforeAdvice:

package com.javarticles;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class AopBeforeAdvice {
    
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethodInJavaArticles()")
    public void beforeAnyMethodInJavArticles() {
        System.out.println("before advice applied before invoking any method in package com.javarticles");
    }
    
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethodInServiceA()")
    public void beforeAnyMethodInServiceA() {
        System.out.println("before advice applied before invoking any method in package com.javarticles.serviceA");
    }    
    
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethod()")
    public void beforeAnyMethod() {
        System.out.println("before advice applied before invoking any method in package com.javarticles and sub-packages");
    } 
    
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethodInTaskA()")
    public void beforeAnyMethodInTaskA() {
        System.out.println("before advice applied before any method in TaskA");
    }    
        
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethodOnInterface()")
    public void beforeAnyMethodOnInterface() {
        System.out.println("before advice applied before invocation of methods from classes implementing ITask type");
    }          
}

Next, make sure you declare TaskB bean in spring container. In order to test this, we will modify the main program to invoke TaskB.doTaskB().
When you run the example, you will see @Before advice beforeAnyMethodOnInterface() called for all the classes that implemented ITask

Output:

before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invoking any method in package com.javarticles.serviceA
a1
before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invoking any method in package com.javarticles.serviceA
a2
before advice applied before invoking any method in package com.javarticles and sub-packages
b1
before advice applied before invoking any method in package com.javarticles and sub-packages
b2
before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invoking any method in package com.javarticles
c1
before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invoking any method in package com.javarticles
c2
before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invoking any method in package com.javarticles.serviceA
before advice applied before any method in TaskA
before advice applied before invocation of methods from classes implementing ITask type
taskA
before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invocation of methods from classes implementing ITask type
taskB

Match Join Points within classes with a custom annotation

In our last section, we will show you how to match join points based on classes annotated with a specific annotation.

We will first define a custom annotation.

EnableDiagnostics:

package com.javarticles;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target( { ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableDiagnostics {
    boolean recordEvent() default false;
}

Next we will apply this annotation at class level to classes TaskB and C.
Then, you can match the join points within the classes that have been annotated with @EnableDiagnostics using the following expression.

    @Pointcut("@within(com.javarticles.EnableDiagnostics)")
    public void onAnyMethodInClassWithCustomAnnotation() {
    }

We will add the pointcut declaration to our bean.

AopWithinPointcutBean:

package com.javarticles;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class AopWithinPointcutBean {    
    
    @Pointcut("within(com.javarticles.*)")
    public void onAnyMethodInJavaArticles() {
    }
    
    @Pointcut("within(com.javarticles.serviceA.*)")
    public void onAnyMethodInServiceA() {
    }
    
    @Pointcut("within(com.javarticles..*)")
    public void onAnyMethod() {
    }
    
    @Pointcut("within(com.javarticles.serviceA.TaskA)")
    public void onAnyMethodInTaskA() {
    }
    
    @Pointcut("within(com.javarticles.ITask+)")
    public void onAnyMethodOnInterface() {
    }
    
    @Pointcut("@within(com.javarticles.EnableDiagnostics)")
    public void onAnyMethodInClassWithCustomAnnotation() {
    }
}

Next, we will add a @Before advice for the declared pointcut.

AopBeforeAdvice:

package com.javarticles;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class AopBeforeAdvice {
    
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethodInJavaArticles()")
    public void beforeAnyMethodInJavArticles() {
        System.out.println("before advice applied before invoking any method in package com.javarticles");
    }
    
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethodInServiceA()")
    public void beforeAnyMethodInServiceA() {
        System.out.println("before advice applied before invoking any method in package com.javarticles.serviceA");
    }    
    
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethod()")
    public void beforeAnyMethod() {
        System.out.println("before advice applied before invoking any method in package com.javarticles and sub-packages");
    } 
    
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethodInTaskA()")
    public void beforeAnyMethodInTaskA() {
        System.out.println("before advice applied before any method in TaskA");
    }    
        
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethodOnInterface()")
    public void beforeAnyMethodOnInterface() {
        System.out.println("before advice applied before invocation of methods from classes implementing ITask type");
    }      
        
    @Before("com.javarticles.AopWithinPointcutBean.onAnyMethodInClassWithCustomAnnotation()")
    public void beforeAnyMethodClassWithCustomAnnotation() {
        System.out.println("before advice applied before any method in class with custom annotation");
    }
}

C:

package com.javarticles;

@EnableDiagnostics(recordEvent=true)
public class C {
    public void c1() {
        System.out.println("c1");
    }

    public void c2() {
        System.out.println("c2");
    }
}

TaskB:

package com.javarticles.serviceB;

import com.javarticles.EnableDiagnostics;
import com.javarticles.ITask;

@EnableDiagnostics(recordEvent=true)
public class TaskB implements ITask {
    public void doTaskB() {
        System.out.println("taskB");
    }
}

SpringAopPointcutExample:

package com.javarticles;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.javarticles.serviceA.A;
import com.javarticles.serviceA.TaskA;
import com.javarticles.serviceB.B;
import com.javarticles.serviceB.TaskB;

public class SpringAopPointcutExample {
    public static void main(String[] args) throws NoSuchMethodException, SecurityException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        try {
           A a = (A) context.getBean("serviceA");
           B b =  (B) context.getBean("serviceB");
           C c =  (C) context.getBean("serviceC");
           TaskA taskA =  (TaskA) context.getBean("taskA");
           TaskB taskB =  (TaskB) context.getBean("taskB");
           a.a1();
           a.a2();
           b.b1();
           b.b2();
           c.c1();
           c.c2();
           taskA.doTaskA();
           taskB.doTaskB();
        } finally {
            context.close();
        }
    }
}

Output:

before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invoking any method in package com.javarticles.serviceA
a1
before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invoking any method in package com.javarticles.serviceA
a2
before advice applied before invoking any method in package com.javarticles and sub-packages
b1
before advice applied before invoking any method in package com.javarticles and sub-packages
b2
before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before any method in class with custom annotation
before advice applied before invoking any method in package com.javarticles
c1
before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before any method in class with custom annotation
before advice applied before invoking any method in package com.javarticles
c2
before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before invoking any method in package com.javarticles.serviceA
before advice applied before any method in TaskA
before advice applied before invocation of methods from classes implementing ITask type
taskA
before advice applied before invoking any method in package com.javarticles and sub-packages
before advice applied before any method in class with custom annotation
before advice applied before invocation of methods from classes implementing ITask type
taskB

Download the source code

This was an example about pointcut designator within.

You can download the source code here: springAopPointcutWithinExample.zip
Share.

Comments are closed.