【问题标题】:Set an AspectJ advise for static method为静态方法设置 AspectJ 建议
【发布时间】:2012-12-06 13:30:49
【问题描述】:

我用原始的 Pointcut 和 Advise 方法编写了简单的 Aspect:

@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
  }
}

我有以下基于 Spring 注释的应用程序配置:

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

以及 com.mtag.util 包中的实用程序类:

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

但是当我打电话时

SomeUtil.someMethod(arg1, arg2);

在单元测试中,我可以看到方法调用没有被拦截并且我的@AfterReturning 建议不起作用。

但如果我将 someMethod() 类型更改为实例(非静态)方法,则切入点

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

并通过添加@Component注解并像这样调用目标方法来管理SomeUtil bean:

@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(...);
    }
}

一切正常。

我可以通过什么方式为静态方法设置 Advice?

【问题讨论】:

  • @AfterReturning(value = "someMethodInvoke())" 你多了一个括号
  • @izhamoidsin,是接受(由我)提供的答案。还是这个不正确?

标签: java aspectj spring-aop


【解决方案1】:

其实spring框架中使用自动代理拦截静态方法的解决方案是没有的。 您应该使用 LWT AspectJ 解决方案。

简而言之,您应该使用相同的注释,但需要进行一些额外的配置。

1) 下一行添加到spring上下文文件中:

<context:load-time-weaver/>

(可能在你的情况下没有必要)

2) 不幸的是,您还应该添加 META-INF/aop.xml。示例:

<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) 启动JVM时的参数

-javaagent:${PATH_TO_LIB }/aspectjweaver.jar

应该添加。

所以这个解决方案相当费力。

欲了解更多信息,请阅读此处的 7.8.4 章节http://docs.spring.io/spring/docs/3.0.0.RC2/reference/html/ch07s08.html

【讨论】:

  • 好答案,尤金。我什至不认为这个解决方案很费力。一旦设置,它将永远工作。 :-) 无论如何,如果你想避免额外的运行时配置,你仍然可以使用编译时编织。
  • 是的,我的意思是这个解决方案很费力,取决于拦截非静态方法,但对我来说,调查起来很费力。 =)
  • @kriegaex 你的意思是说我们也可以用Spring AOP的编译时编织来拦截静态方法吗?
  • @Kwadz,您可以将 CTW 与 AspectJ 一起使用,那么您不再需要 Spring AOP。但是,如果这是您的问题,您仍然可以将 Spring AOP 用于其他方面。
  • Spring AOP 不需要支持 AspectJ CTW,因为后者独立于 Spring。是的,AspectJ 支持拦截静态方法。 P.S.:Spring AOP 对 AspectJ LTW 有特殊支持,请参阅 Spring AOP manual。但正如我所说,无论有没有 Spring,CTW 也是可能的。
猜你喜欢
  • 2013-11-17
  • 2014-06-26
  • 2011-01-25
  • 1970-01-01
  • 2010-11-29
  • 2020-02-23
  • 1970-01-01
  • 2011-08-16
  • 1970-01-01
相关资源
最近更新 更多