为Spring MVC / AOP应用程序实现动态菜单


问题内容

我希望为我的Spring MVC应用程序实现动态可变的菜单(在添加注释的方法或控制器时进行更新)。

我想要的是引入新的批注(@RequestMenuMapping),该批注将用于@Controllerbean及其方法(就像@RequestMapping作品一样)。

这是我想要的,User课,制作菜单像

Users
    Index | List | Signup | Login

使用以下代码:

@Controller
@RequestMapping("user")
@RequestMenuMapping("Users")
public class User {

    @RequestMapping("")
    @RequestMenuMapping("Index")
    public String index(/* no model here - just show almost static page (yet with JSP checks for authority)*/) {
        return "user/index.tile";
    }

    @RequestMapping("list")
    @RequestMenuMapping("List")
    public String list(Model model) {

        model.addAttribute("userList",/* get userlist from DAO/Service */);

        return "user/list.tile";
    }

    @RequestMapping("signup")
    @RequestMenuMapping("Signup")
    public String signup(Model model) {

        model.addAttribute("user",/* create new UserModel instance to be populated by user via html form */);

        return "user/signup.tile";
    }

    @RequestMapping("login")
    @RequestMenuMapping("Login")
    public String login(Model model) {

        model.addAttribute("userCreds",/* create new UserCreds instance to be populated via html form with login and pssword*/);

        return "user/login.tile";
    }
}

我认为Spring
AOP可能会帮助我通过@RequestMenuMapping注释@AfterReturning添加切入点方法,并通过向模型添加表示网站菜单的内容。

但这提出了两个问题:

  1. 如果建议方法中缺少Model实例,如何在@AfterReturning建议方法中获取实例(如.index())?
  2. 为了建立完整的菜单索引,如何获取带有注释的所有方法(如在Java Reflection中Method)和类(如在Java Reflection中Class@RequestMenuMapping

问题答案:

拦截器演示:

@Aspect
@Component
public class InterceptorDemo {

  @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
  public void requestMapping() {
  }
  @Pointcut("@annotation(you.package.RequestMenuMapping)")
  public void requestMenuMapping() {
  }


  @AfterReturning("requestMapping() && equestMenuMapping()")
  public void checkServer(JoinPoint joinPoint,Object returnObj) throws Throwable {
      Object[] args = joinPoint.getArgs();
      Model m = (Model)args[0];
      // use joinPoint get class or methd...
  }
}

如果您想用自己的东西拦截Contoller,则可以编写另一个切入点,使ProceedingJoinPoint对象可以得到想要的东西。