該注解顧名思義增強器,對注解了Controller類的增強,@ControllerAdvice的實現:
/** * Specialization of {@link Component @Component} for classes that declare * {@link ExceptionHandler @ExceptionHandler}, {@link InitBinder @InitBinder}, or * {@link ModelAttribute @ModelAttribute} methods to be shared across * multiple {@code @Controller} classes. * * performance and add complexity. * * @author Rossen Stoyanchev * @author Brian Clozel * @author Sam Brannen * @since 3.2 */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface ControllerAdvice {
部分源碼,該注解使用@Component注解,這樣的話當我們使用<context:component-scan>掃描時也能掃描到。看注釋@link意思即把@ControllerAdvice注解內部使用@ExceptionHandler、@InitBinder、@ModelAttribute注解的方法應用到所有的 @RequestMapping注解的方法。
1.@ExceptionHandler(異常類)這個注解則表示Controller中任何一個方法發生異常,則會被注解了@ExceptionHandler的方法攔截到。對應的異常類執行對應的方法,如果都沒有匹配到異常類,則采用近親匹配的方式。
2.@ModelAttribute有三個作用
①綁定請求參數到命令對象:放在功能處理方法的入參上時,用於將多個請求參數綁定到一個命令對象,從而簡化綁定流程,而且自動暴露為模型數據用於視圖頁面展示時使用;
②暴露表單引用對象為模型數據:放在處理器的一般方法(非功能處理方法)上時,是為表單准備要展示的表單引用對象,如注冊時需要選擇的所在城市等,而且在執行功能處理方法(@RequestMapping注解的方法)之前,自動添加到模型對象中,用於視圖頁面展示時使用;
③暴露@RequestMapping方法返回值為模型數據:放在功能處理方法的返回值上時,是暴露功能處理方法的返回值為模型數據,用於視圖頁面展示時使用。
@ControllerAdvice public class CurrentUserControllerAdvice { private static final Logger log = LoggerFactory.getLogger(CurrentUserControllerAdvice.class); @ModelAttribute("currentUser") public CurrentUser getCurrentUser(Authentication auth, HttpServletRequest request, HttpServletResponse response) throws Exception { CurrentUser user = (auth == null) ? null : (CurrentUser) auth.getPrincipal(); log.debug("CurrentUser={}, URL={}", user, request.getRequestURL()); if (user != null) { log.debug("Username={}, Role={}", user.getUsername(), user.getRole()); } return user; } }
這段代碼的意思則為把返回的user對象設置到Model中,對於之后的RequestMapping的方法調用可以直接取得到對應key值currentUser的value值。對於一個用戶認證實現可以使用這個注解。