Spring AOP aspect around not executing
Asked Answered
T

1

5

I want to count now much my method worked. So I use Around aspect but it doesn't work. Neither with annotations nor XML. Dubgger shows that Aspect hasn't been invoked. Unfortunatly, non of examples helped.

TimeCountAspect.java

@Aspect
@Component
public class TimeCountAspect {

     @Around("execution(* com.springapp.Calculation.Calculator.calculate(..))")
     public Object timeCounterClass(ProceedingJoinPoint joinpoint) {
         Object result = null;
         try {
            System.out.println("Preparing to calculate");
            long start = System.currentTimeMillis(); // Before

             result = joinpoint.proceed(); // Method invoke

             long end = System.currentTimeMillis(); // After
             System.out.println("Calculation took " + (end - start)
                     + " milliseconds.");
         } catch (Throwable t) {
             System.out.println("Nothing happend!");
         }
         return result;
     }
 }

It perfectly sees all classes and they are connected with declaration of beans in XML. (IntelliJ Idea shows it). XML snippet

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

 <mvc:annotation-driven/>
 <mvc:resources mapping="/resources/**" location="/"/>


<!-- Enable AspectJ style of Spring AOP -->
<aop:aspectj-autoproxy/>

<aop:aspectj-autoproxy proxy-target-class="true">
    <aop:include name="timeCounterAspect" />
</aop:aspectj-autoproxy>


<bean id="timeCounterAspect" class="com.springapp.Calculation.TimeCountAspect"/>

<aop:config>
    <aop:aspect id="timeCount" ref="timeCounterAspect">
        <aop:pointcut id="calculation" expression=
                "execution(* com.springapp.Calculation.Calculator.calculate(..))"/>
        <aop:around
                pointcut-ref="calculation"
                method="timeCounterClass"/>
    </aop:aspect>
</aop:config>

................factories and other things............

</beans>

POM.XML snippet

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>${aspect.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>${spring.version}</version>
</dependency>

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>${aspect.version}</version>
</dependency>

calculate() method to which aspect I want apply to. There is method call() that invokes method calculate()

  public BigDecimal calculate(int numberOfThreads, int precision) {
      ................
     return summ;
  }


 public BigDecimal call() throws Exception {
        return calculate(Calculator.numberOfThreads, Calculator.precision);
    }
Touslesmois answered 2/7, 2014 at 13:58 Comment(6)
Sprnig uses proxies to apply AOP, resulting in only external method calls to be intercepted not internal method calls.Jayme
I've tried to apply it to call() method, but there are no difference.Touslesmois
First start with cleaning your configuration you have 3 aspects defined. You only need the aspect declaration and <aop:aspectj-autoproxy />. Also the aspect will only operate on beans defined in the same application context. So if you also have a COntextLoaderListener loading beans those aren't affected by this aspect.Jayme
Well, I tried all the variants - with XML and without but nothing helps. Also I tried with defferent methods.Touslesmois
As mentioned AOP will only work in beans defined in the same applicationcontext. If they aren't defined ni the same context or if you aren't using the spring managed instance it isn't going work.Jayme
I don't know why, but it has begun to work with another methods, such as login. They all are in one applicationcontext.Touslesmois
M
12

You are using Spring AOP, which works in proxy model. Which means it creates a wrapping proxy over the actual beans. The well known limitations of this setup are:

  • interception on method executions from external calls only
  • unawareness to local calls (or calls with this or super)
  • interception on public members only (private/protected can't be intercepted)
  • it is not possible to have aspects themselves be the target of advice from other aspects. The @Aspect annotation on a class marks it as an aspect, and hence excludes it from auto-proxying.

You are trying to intercept the local calls within the bean itself, which you cannot achieve with this setup.

To overcome the above limitations you need to setup up native AspectJ based weaving environment.

References: Spring-Framework-Reference

Moussorgsky answered 13/1, 2015 at 13:23 Comment(1)
Thanks, Dev. It is solved a long time ago - the first item was the solution. But such information is always helpful.Touslesmois

© 2022 - 2024 — McMap. All rights reserved.