Java Aspectj切入点表达式在单个类中不适用于一个方法而适用于另一个方法

Java Aspectj切入点表达式在单个类中不适用于一个方法而适用于另一个方法,java,spring,aop,aspectj,Java,Spring,Aop,Aspectj,我已经在controller中编写了以下代码 对于此controllerMethod方法,aspectj切入点表达式工作正常,但对于executeService方法,aspectj切入点表达式不工作 @RequestMapping(value = "URL", method = RequestMethod.POST) public ModelAndView controllerMethod(@ModelAttribute ModelAttribute reqModel, HttpServletR

我已经在controller中编写了以下代码

对于此controllerMethod方法,aspectj切入点表达式工作正常,但对于executeService方法,aspectj切入点表达式不工作

@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方法之前执行aspect。

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

因为
AOP
不拦截内部调用,所以您可以添加一个self-controller字段,并通过
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....
    }
}

虽然我们的同事提供了正确的答案,但我将进行总结

在aspects实现方面,spring会生成一个封装控制器的代理。 代理的实现方式是,它有特殊的钩子来调用类前后的方面(或前后,完全改变流)

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

  • 基于java.lang.Proxy的
  • 基于CGLIB的
第一种方法通常更好、更快,但只适用于接口。生成的代理是实现接口所有方法的“东西”。实现方法包含我之前提到过的那些钩子,但是由于这些方法只是接口中的方法,它们必须是
public

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

现在,很明显这不能真正用于私有方法,因为不可能重写私有方法。 这就是为什么我的同事指出,
private
在这里不起作用

现在关于自我注射的东西

当您在原始控制器的方法中,并且您试图调用另一个方法(即使它是公共的)时,您不再使用代理,而是在代理之后使用原始类。 所以这意味着您将无法利用“增强”方法。 这就是为什么会有自注入-您可以看到(例如,使用调试器)自注入依赖实际上是一个具有所有代理的依赖,这就是它开始工作的原因

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


希望这有助于理解幕后的工作方式

Spring使用AOP代理,只截获对对象的方法调用,不截获内部方法调用。我已将私有方法更改为公共方法。仍然不适用于我。在代码中添加一个名为
self
且带有注释
@Autowire
的self-controller文件。然后调用
executeService
类似于“self.executeService”的函数来阅读注释。。不管修改器是什么,它仍然是一个内部方法调用。Self Autowire也不起作用,因为它正在抛出错误。找不到资源。您在Spring 4.3上吗?只有Spring4.3是Spring的一个全新版本,官方才支持自动布线的自注入。旧的方法是使用@Resource注释。看这里,我在旧版本3.2上。将更改为@Resource注释。