1

I have written below code in controller.

For this controllerMethod method the aspectj Pointcut expression is working fine but for executeService method Aspect is not working.

@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....
}

I have written the aspect as below.

@Before("execution(* com.*.*.Controller.executeService(..))")
public void logBefore(JoinPoint joinPoint) {
    logger.info("Before aspect: " + joinPoint.getSignature().getName());
}

Can you please let me know where is the issues. I need to execute aspect before calling executeService method.

3 Answers3

1

Because the AOP not intercept internal call ,so you can add a self-controller field,and call the internal method by self.method(...). Following code:

@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....
    }
}
dabaicai
  • 999
  • 8
  • 9
0

You need to @RequestMapping(value = "URL", method = RequestMethod.POST) direct to executeService then its work.

T L Patel
  • 86
  • 5
0

Although our colleagues have provided correct answers, I'll summarize.

When it comes to aspects implementation, spring generates a proxy that wraps your controller. The proxy is implemented in a way that it has special hooks to invoke aspects before and after the class (or around, altering the flow altogether).

Spring uses two different strategies for proxy generation:

  • java.lang.Proxy based
  • CGLIB based

The first one is in general better, faster but works only with interfaces. The generated proxy is "something" that implements all the methods of the interface. The implementation methods contain those hooks I've talked before, but since the methods are only methods in the interface they have to be public

CGLIB - is slower, but it can work with classes as well (with some restrictions though). The way it works is sub-classing the parent class and overriding the methods provided by the super class. This new method (let's call it foo) will call all the hooks and somewhere in code if needed will call super.foo().

Now, obviously this can't really work with private methods because its impossible to override private methods. That's why my colleagues have pointed that private won't work here.

Now regarding the self injection stuff:

When you're inside the method of original controller and you're trying to call just another method (even if its public), you're not working with proxy any more, you're kind of behind the proxy and work with original class. So this means that you won't be able to take advantage of "enhanced" method.

That's why there is a self injection - you can see (with debugger for example) that the self-injected dependency is actually a dependency with all the proxies, that's why it starts to work.

Another workaround is to refactor the method to another Spring bean, inject this bean to your controller, and provide a definition for that bean.

halfer
  • 19,824
  • 17
  • 99
  • 186
Mark Bramnik
  • 39,963
  • 4
  • 57
  • 97
  • Self Autowire is also not working as it is throwing error. Not able to find the resource. – Prashant Chindhade Jun 05 '17 at 08:18
  • Are you on Spring 4.3? Self injection with autowiring is officially supported only in Spring 4.3 which is a pretty new version of spring. An older way is using @Resource annotation. See here https://stackoverflow.com/questions/5152686/self-injection-with-spring – Mark Bramnik Jun 05 '17 at 08:24
  • Ya, I am on old version 3.2. Will change to @Resource annotation. – Prashant Chindhade Jun 05 '17 at 09:24