Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring AOP aspect around not executing

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);
    }
like image 490
Devour Avatar asked Feb 13 '23 14:02

Devour


1 Answers

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

like image 182
Dev Naruka Avatar answered Feb 15 '23 08:02

Dev Naruka