我正在尝试使用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中初始化。但是,当我尝试运行作业时,不会触发切入点。为什么会发生这种情况?有什么办法可以解决?

最佳答案

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


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

08-18 19:59
查看更多