Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set an AspectJ advise for static method

I have written simple Aspect with primitive Pointcut and Advise method:

@Aspect
public class MyAspect {

  @Pointcut("execution(static * com.mtag.util.SomeUtil.someMethod(..))")
  public void someMethodInvoke() { }

  @AfterReturning(value = "someMethodInvoke())", returning = "comparisonResult")
  public void decrementProductCount(List<String> comparisonResult) {
    //some actions
  }
}

I have following Spring annotation-based application config:

@Configuration
@EnableAspectJAutoProxy
public class AppConfig { 
  //...
}

And utility class in com.mtag.util package:

public class SomeUtil {
  static List<String> someMethod(List<String> oldList, List<String> newList) {
    //...
  } 
}

but when I call

SomeUtil.someMethod(arg1, arg2);

in unit test I can see that method call is not intercepted and my @AfterReturning advise is not working.

But if i change someMethod() type to instance (non-static) method, pointcut to

@Pointcut("execution(* com.mtag.util.SomeUtil.someMethod(..))")

and manage SomeUtil bean by Spring by adding @Component annotation and call target metod like this:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {AppConfig.class}, loader = AnnotationConfigContextLoader.class)
public class SomeUtilTest {

    @Autowired
    private SomeUtil someUtil;

    @Test
    public void categoriesDiffCalc() {
        List<String> result = someUtil.someMethod(...);
    }
}

Everything is OK.

In what way I can set an Advice for static method?

like image 366
izhamoidsin Avatar asked Dec 06 '12 13:12

izhamoidsin


1 Answers

Actually there is no solutions to intercept static methods using auto proxy in spring framework. You should use the LWT AspectJ solution.

In a nutshell you should use the same annotations but with some additional configuration.

1) add to the spring context file next line:

<context:load-time-weaver/>

(may be in your situation it is not necessary)

2) unfortunately you should also add META-INF/aop.xml. Example:

<weaver>
    <include within="com.example.ClassA"/> <!-- path to concrete class -->
    <include within="com.log.* "/> <!—- path to aspects package -->
</weaver>
<aspects>
    <aspect name="com.log.AspectA"/>
</aspects>

3) when starting JVM the argument

-javaagent:${PATH_TO_LIB }/aspectjweaver.jar

should be added.

So this solution is rather laborious.

For more information read 7.8.4 chapter here http://docs.spring.io/spring/docs/3.0.0.RC2/reference/html/ch07s08.html

like image 143
Eugene Stepanenkov Avatar answered Sep 21 '22 15:09

Eugene Stepanenkov