父抽象类中方法的切入点

时间:2018-06-15 12:33:50

标签: java spring aspectj spring-aop pointcut

我有一个场景,我的拦截方法是在父类中,并且在切入点类中没有被覆盖。 以下是示例类:

public abstract class A{
@RequestMapping(value = "/data", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String getData(@RequestBody String request) throws Exception {
    return "dummy";
}
}

@RestController
public class B extends A {
}

我的观点定义为:

@Aspect
@Component
public class RestCallLogger {
    @Pointcut("within(com.test..*) && within(@org.springframework.web.bind.annotation.RestController *)")
    public void restControllers() {
    }

    @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
    public void requestMappingAnnotations() {
    }

    @Around("restControllers() && requestMappingAnnotations()")
    public Object onExecute(ProceedingJoinPoint jp) throws Throwable {
        Object result = null;
        try {
            result = jp.proceed();
        } catch (Exception ex) {
            throw ex;
        }
        return result;
    }
}

但它不起作用。如果我使用Annotation @RestController标记A类并使其具体化,那么它可以工作。 问题是如何在父抽象类中为方法创建"切入点"? PS:我无法将代码的层次结构更改为现有代码。

1 个答案:

答案 0 :(得分:1)

对我而言,这是有效的。这是一个MCVE

package de.scrum_master.app;

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

public abstract class A {
  @RequestMapping(value = "/data", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
  public String getData(@RequestBody String request) throws Exception {
    return request;
  }
}
package de.scrum_master.app;

import org.springframework.web.bind.annotation.RestController;

@RestController
public class B extends A {}
package de.scrum_master.app;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ComponentScan(basePackages = { "de.scrum_master" })
public class Application2 {
  public static void main(String[] args) throws Exception {
    ApplicationContext appContext = new AnnotationConfigApplicationContext(Application2.class);
    B b = (B) appContext.getBean("b");
    System.out.println(b.getData("bbb"));
    A a = (A) appContext.getBean("b");
    System.out.println(a.getData("aaa"));
  }
}
package de.scrum_master.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class RestCallLogger {
  @Pointcut("within(de.scrum_master..*) && @target(org.springframework.web.bind.annotation.RestController)")
  public void restControllers() {}

  @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
  public void requestMappingAnnotations() {
  }

  @Around("requestMappingAnnotations()")
  public Object onExecute(ProceedingJoinPoint jp) throws Throwable {
    System.out.println(jp);
    Object result = null;
    try {
      result = jp.proceed();
    } catch (Exception ex) {
      throw ex;
    }
    return result;
  }
}

控制台日志说:

execution(String de.scrum_master.app.A.getData(String))
bbb
execution(String de.scrum_master.app.A.getData(String))
aaa

你的情况有什么不同?