Announcement Announcement Module
Collapse
No announcement yet.
Difference between within and execution Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Difference between within and execution

    I tried searching the forums to find the difference between the two but didn't come up with any good explanations. I have just started working with aspects in general and I'm a bit confused by the two.

    My requirement is to advice all methods in my service and dao packages and so far I have been using the within designator.

    The spring documentation states :
    execution - for matching method execution join points, this is the primary pointcut designator you will use when working with Spring AOP

    within - limits matching to join points within certain types (simply the execution of a method declared within a matching type when using Spring AOP)

    My questions:
    1. Am I correct in my use of within or should I switch to execution?
    2. Also it is my understanding that execution is applied only to methods while within is applied to annotations etc also. Am I correct?
    3. How do I have the aspect applied to two different packages(different hierarchies) using within?

  • #2
    Originally posted by NubKnacker View Post
    ...
    My requirement is to advice all methods in my service and dao packages and so far I have been using the within designator.
    ...
    1. Am I correct in my use of within or should I switch to execution?
    Not at all. 'Within' is so-called lexical-structure based pointcut. That means that it captures all the join points within the body of the specified classes, as well as any nested classes. Let me illustrate that:

    AopService.java
    Code:
    package com.spring.aop;
    
    import org.springframework.stereotype.Component;
    
    @Component
    public class AopService {
    
    	@Component
    	public static class Nested {
    		public void testNested() {
    			System.out.println("xxxxxxxx: AopService$Nested.testNested()");
    		}
    	}
    
    	public AopService() {
    		System.out.println("");
    	}
    
    	public void service() {
    		System.out.println("xxxxx: AopService.service()");
    	}
    }
    TestAspect.java
    Code:
    package com.spring.aop;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.stereotype.Component;
    
    @Component
    @Aspect
    public class TestAspect {
    
    	@Around("within(com.spring.aop.AopService)")
    	public Object advice(ProceedingJoinPoint joinPoint) throws Throwable {
    		System.out.println("xxxxxxxxxxxx: TestAspect.advice(): aspect is called on " + joinPoint
    			+ ". This object: " + joinPoint.getThis());
    		return joinPoint.proceed();
    	}
    }
    SpringStart.java
    Code:
    package com.spring;
    
    import com.spring.aop.AopService;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class SpringStart {
    	public static void main(String[] args) throws Exception {
    		ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
    		AopService bean = (AopService)context.getBean("aopService");
    		bean.service();
    		AopService.Nested nested = (AopService.Nested)context.getBean("aopService.Nested");
    		nested.testNested();
    	}
    }
    spring-config.xml
    HTML Code:
    <?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"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:util="http://www.springframework.org/schema/util"
           xsi:schemaLocation="
      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
      http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
    
    	<context:component-scan base-package="com.spring.aop"/>
    	<aop:aspectj-autoproxy proxy-target-class="true"/>
    
    </beans>
    Output shows that AopService.Nested.testNested() call is advised.
    Change pointcut definition at TestAspect to the following and check the result: @Around("execution(* com.spring.aop.AopService.*(..))"). You see that nested class method call is not advised.

    About your initial question - it's up to you to decide what pointcut suits more to your architecture and business requirements. I can say just that 'execution' pointcut is more fine-grained than 'within'.

    Originally posted by NubKnacker View Post
    ...
    2. Also it is my understanding that execution is applied only to methods while within is applied to annotations etc also. Am I correct?
    The question is not clear. Hope that explanation about the difference between within and execution pointcuts provided you with the answer.

    Originally posted by NubKnacker View Post
    ...
    3. How do I have the aspect applied to two different packages(different hierarchies) using within?
    You can use standard pointcut language facilities - 6.2.3.2. Combining pointcut expressions.

    Comment


    • #3
      Originally posted by denis.zhdanov View Post
      About your initial question - it's up to you to decide what pointcut suits more to your architecture and business requirements. I can say just that 'execution' pointcut is more fine-grained than 'within'.
      Thanks for your wonderful explanation. Really appreciate it.

      Originally posted by denis.zhdanov View Post
      The question is not clear. Hope that explanation about the difference between within and execution pointcuts provided you with the answer.
      The within pointcut allows you to do @within(org.springframework.transaction.annotation .Transactional). This means that any method which has the @Transactional annotation will be advised. Is it possible to do the same using execution?

      Comment


      • #4
        Originally posted by NubKnacker View Post
        The within pointcut allows you to do @within(org.springframework.transaction.annotation .Transactional). This means that any method which has the @Transactional annotation will be advised. Is it possible to do the same using execution?
        'within' and '@within' are two different pointcut designators. Full list is mentioned at the reference - 6.2.3.1. Supported Pointcut Designators. There is no '@execution' pointcut, the closest are '@target' and '@annotation'.

        Comment


        • #5
          Originally posted by denis.zhdanov View Post
          'within' and '@within' are two different pointcut designators. Full list is mentioned at the reference - 6.2.3.1. Supported Pointcut Designators. There is no '@execution' pointcut, the closest are '@target' and '@annotation'.
          Thanks. A true 'duh' moment for me. Funny how I missed that completely.

          Comment

          Working...
          X