Aspectj Pointcut表达式不适用于一个方法,也适用于单个类中的另一个方法

时间:2017-06-05 07:10:00

标签: java spring aop aspectj

我在控制器中写了下面的代码。

对于这个 controllerMethod 方法,aspectj Pointcut表达式工作正常,但对于 executeService 方法,Aspect不起作用。

@RequestMapping(value = "URL", method = RequestMethod.POST)
public ModelAndView controllerMethod(@ModelAttribute ModelAttribute reqModel, HttpServletRequest req, HttpServletResponse res) {

    try {
        response = executeService(param1, param2);

    } catch (Exception e) {

    }

    }       
private ResponseObject executeService(String param1, String param2){
    //Code....
}

我写的方面如下。

@Before("execution(* com.*.*.Controller.executeService(..))")
public void logBefore(JoinPoint joinPoint) {
    logger.info("Before aspect: " + joinPoint.getSignature().getName());
}
你可以告诉我问题在哪里。我需要在调用 executeService 方法之前执行方面。

3 个答案:

答案 0 :(得分:0)

你需要@RequestMapping(value =“URL”,method = RequestMethod.POST)直接到 executeService然后它的工作。

答案 1 :(得分:0)

由于AOP没有拦截内部调用,因此您可以添加自控制器字段,并通过self.method(...)调用内部方法。 以下代码:

@Controller
public class ExampleController{

    @Autowired
    private ExampleController self;

    @RequestMapping(value = "URL", method = RequestMethod.POST)
    public ModelAndView controllerMethod(@ModelAttribute ModelAttribute reqModel, HttpServletRequest req, HttpServletResponse res) {

        try {
            response = self.executeService(param1, param2);

        } catch (Exception e) {

        }

    }
    public ResponseObject executeService(String param1, String param2){
        //Code....
    }
}

答案 2 :(得分:0)

虽然我们的同事提供了正确的答案,但我会总结一下

当涉及方面实现时,spring会生成一个包装控制器的代理。 代理的实现方式是它具有特殊的钩子来调用类之前和之后的方面(或者围绕完全改变流程)。

Spring使用2种不同的代理生成策略:

  • 基于java.lang.Proxy
  • 基于CGLIB

第一个通常更好,更快,但仅适用于接口。生成的代理是实现接口所有方法的“东西”。实现方法包含我之前谈过的那些钩子,但由于这些方法只是接口中的方法,因此它们必须是public

CGLIB - 速度较慢,但​​它也适用于类(虽然有一些限制)。它的工作方式是子类化父类并重写超类提供的方法。这个新方法(让我们称之为 foo )将调用所有钩子和代码中的某个地方(如果需要)将调用super.foo()

现在,显然这对私有方法无效,因为它无法覆盖私有方法。 这就是为什么我的同事指出private在这里不起作用。

现在关于自我注射的东西。

当你进入原始控制器的方法并且你试图只调用另一种方法时(即使它是公共的),你不再使用代理了,你有点落后于代理并使用原班。 所以这意味着你将无法利用“增强”方法。 这就是自我注入的原因 - 你可以看到(例如调试器)自注入依赖实际上是所有代理的依赖,这就是它开始工作的原因。

另一种解决方法是将该方法重构为另一个spring bean,将此bean注入您的控制器并为该bean提供定义

希望这有助于了解事情在幕后的工作原理