AOP Pointcut匹配Spring Step.execute(...)方法

时间:2014-10-29 20:25:59

标签: java aspectj spring-batch

我正在尝试使用AspectJ AOP来拦截对Spring Batch Step执行的调用,并建议登录哪个文件。

按照this example中的配置,我的切入点如下所示:

@Before("execution(* org.springframework.batch.core.Step.execute(..)) && " + "args(stepExecution)")
public void setupLogging(Object stepExecution) {...}

@After("execution(* org.springframework.batch.core.Step.execute(..))")
public void tearDownLogging() {...}

使用以下测试(以及当我拆除日志记录时的类似测试),切入点匹配,但在我尝试部署它们时似乎不起作用。

@Test
    public void testSetupLoggingMatcher() throws NoSuchMethodException, SecurityException {
        java.lang.reflect.Method method = LoggingAspect.class.getMethod("setupLogging", Object.class);
        Annotation[] annotations = method.getDeclaredAnnotations();

        boolean matched = false;
        for (Annotation annotation: annotations) {
            if (annotation.annotationType() == org.aspectj.lang.annotation.Before.class) {
                org.aspectj.lang.annotation.Before beforeAnnotation = (org.aspectj.lang.annotation.Before) annotation;
                String pointcutstring = beforeAnnotation.value();
                PointcutParser pointcutParser =
                        PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution();
                Collection<PointcutParameter> parameters = new ArrayList<PointcutParameter>();
                parameters.add(new PointcutParameter() {

                    @Override
                    public Class getType() {
                        return StepExecution.class;
                    }

                    @Override
                    public String getName() {
                        return "stepExecution";
                    }

                    @Override
                    public Object getBinding() {
                        return mockStepExecution;
                    }
                });
                PointcutExpression pointcut =
                        pointcutParser.parsePointcutExpression(pointcutstring, LoggingAspect.class,
                                parameters.toArray(new PointcutParameter[0]));
                ShadowMatch match = pointcut.matchesMethodExecution(Step.class.getMethod("execute", StepExecution.class));
                matched = matched || match.alwaysMatches();
            }
        }
        assertTrue("No pointcuts on setupLogging matched Step.execute(StepExecution.class)", matched);
    }

我已经验证我的切入点与Step接口匹配,并且我的Aspect正在ApplicationContext中初始化。但是,当我尝试运行作业时,切入点不会被触发。为什么会这样?有没有办法解决它?

2 个答案:

答案 0 :(得分:1)

您的execution()切入点与具有任意数量参数的方法调用匹配。因此,您需要告诉args()找到参数stepExecution相对于其他参数的位置,以使其与多个参数匹配方法,例如

  • 第一个参数:args(stepExecution, ..)
  • 第二个参数:args(*, stepExecution, ..)
  • 第三个参数:args(*, *, stepExecution, ..)
  • 最后一个参数:args(.., stepExecution)

答案 1 :(得分:0)

我最终放弃了AOP,并将我之前的Aspect转换为StepListener,运行良好。