Need help creating a specific pointcut that utilizes a value from a method annotation

核能气质少年 提交于 2019-12-13 05:09:24

问题


I have the following method

    @AutoHandling(slot = FunctionalArea.PRE_MAIN_MENU)
    @RequestMapping(method = RequestMethod.GET)
    public String navigation(ModelMap model) {
        logger.debug("navigation");
        ...

            //First time to the Main Menu and ID-Level is ID-1 or greater
            if (!callSession.getCallFlowData().isMainMenuPlayed()
                    && callSession.getCallFlowData().getIdLevel() >= 1) {
                // Call Auto Handling                    
                logger.info("Call AutoHandling");
                autoHandlingComponent.processAutoHandling();
            }
        ...

        return forward(returnView);
    }

Basically what I want to do, is have a pointcut on processAutoHandling() But in the @After, I need to use the slot() for @AutoHandling

I tried this, but it does not get called

@Pointcut("execution(* *.processAutoHandling())")
public void processAutoHandleCall() {
    logger.debug("processAutoHandleCall");
}

@Around("processAutoHandleCall() &&" +
        "@annotation(autoHandling) &&" +
        "target(bean) "
)
public Object processAutoHandlingCall(ProceedingJoinPoint jp,
                                      AutoHandling autoHandling,
                                      Object bean)
        throws Throwable {
         ...

回答1:


You can use the wormhole design pattern for this. I am illustrating using AspectJ byte-code based approach and syntax, but you should be able to get the same effect using an explicit ThreadLocal if you are using Spring's proxy-based AOP.

pointcut navigation(AutoHandling handling) : execution(* navigation(..)) 
                                             && @annotation(handling);

// Collect whatever other context you need
pointcut processAutoHandleCall() : execution(* *.processAutoHandling());

pointcut wormhole(AutoHandling handling) : processAutoHandleCall() 
                                           && cflow(navigation(handling));

after(AutoHandling handling) : wormhole(hanlding) {
   ... you advice code
   ... access the slot using handling.slot()
}



回答2:


a) It can't work, you are trying to match two different things:

@Around("processAutoHandleCall() &&" +
        "@annotation(autoHandling) &&" +
        "target(bean) "
)

processHandleCall() matches the inner method execution autoHandlingComponent.processAutoHandling() while @annotation(autoHandling) matches the outer method execution navigation(ModelMap model)

b) since you are obviously trying to advise a Controller, there are a few caveats:

  • if you use proxy-target-class=true everything should work as is, just make sure you don't have any final methods
  • if you don't, all your controller methods must be backed by an interface and the @RequestMapping etc annotations must be on the interface, not the implementing class as described in this section of the Spring MVC reference docs


来源:https://stackoverflow.com/questions/4759803/need-help-creating-a-specific-pointcut-that-utilizes-a-value-from-a-method-annot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!