1. 程式人生 > >項目中AOP的實例應用

項目中AOP的實例應用

清理 edi public 管理員權限 pan 其中 final autowire red

其中包括了權限管理、表單驗證、事務管理、信息過濾、攔截器、過濾器、頁面轉發等等。

公司項目的應用:(涉及用戶驗證登錄以及用戶是否有管理員權限、心理用戶權限等),還有涉及的其他日誌管理代碼就不一一舉例了;

/**
 * 登錄攔截器(登錄判斷)
 * @author alex
 *
 */
public class LoginInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private UserService userService;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws
Exception { if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; //check login Login login = handlerMethod.getMethodAnnotation(Login.class); if (null == login) { return true; }
int userId = 0; String uid = CookieUtil.getValueByName(request, CookieUtil.SESSION_USER); if(NumberUtils.isNumber(uid)){ userId = Integer.valueOf(uid); } if(userId==0 || !userService.isLogined(userId, CookieUtil.getValueByName(request, CookieUtil.SESSION_ID))){ response.sendRedirect(
"/login"); return false; } //set user info User user = userService.getUserById(userId); request.setAttribute("userSession", user); request.setAttribute("loginUsername",user.getUsername()); request.setAttribute("loginUserId",user.getId()); //******* 是內部測試的心理賬戶 request.setAttribute("psychologyUser", user.getType == *** || "*******".equals(user.getCellphone())); //check admin permission Admin admin = handlerMethod.getMethodAnnotation(Admin.class); if (admin!=null && !user.isAdmin()) { response.sendRedirect("/error/no_permission"); return false; } return true; } return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
/**
 * 登錄註解
 * @author Alex
 *
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Login {
    int value() default 0;
}


/**
 * 管理員註解
 * @author Alex
 *
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Admin {
    int value() default 0;
}

一般情況下,對來自瀏覽器的請求的攔截,是利用Filter實現的,這種方式可以實現Bean預處理、後處理。
Spring MVC的攔截器不僅可實現Filter的所有功能,還可以更精確的控制攔截精度。

Spring為我們提供了org.springframework.web.servlet.handler.HandlerInterceptorAdapter這個適配器,繼承此類,可以非常方便的實現自己的攔截器。他有三個方法:

  1. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
  2. throws Exception {
  3. return true;
  4. }
  5. public void postHandle(
  6. HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
  7. throws Exception {
  8. }
  9. public void afterCompletion(
  10. HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
  11. throws Exception {
  12. }


分別實現預處理、後處理(調用了Service並返回ModelAndView,但未進行頁面渲染)、返回處理(已經渲染了頁面)

preHandle預處理回調方法,實現處理器的預處理(如登錄檢查),第三個參數為響應的處理器;

返回值:true表示繼續流程(如調用下一個攔截器或處理器);

false表示流程中斷(如登錄檢查失敗),不會繼續調用其他的攔截器或處理器,此時我們需要通過response來產生響應;

postHandle後處理回調方法,實現處理器的後處理(但在渲染視圖之前),此時我們可以通過modelAndView(模型和視圖對象)對模型數據進行處理或對視圖進行處理,modelAndView也可能為null。

afterCompletion整個請求處理完畢回調方法,即在視圖渲染完畢時回調,如性能監控中我們可以在此記錄結束時間並輸出消耗時間,還可以進行一些資源清理,類似於try-catch-finally中的finally,但僅調用處理器執行鏈中preHandle返回true的攔截器的afterCompletion

AOP相關配置:<tx:advice id="txAdvice" transaction-manager="transactionManager">

        <tx:attributes>  
            <tx:method name="save*" propagation="REQUIRED" rollback-for="Exception"/>  
            <tx:method name="insert*" propagation="REQUIRED"  rollback-for="Exception"/>  
            <tx:method name="del*" propagation="REQUIRED" rollback-for="Exception"/>  
            <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>  
            <tx:method name="find*" read-only="true" />  
            <tx:method name="get*" read-only="true" />  
            <tx:method name="select*" read-only="true" />  
        </tx:attributes>  
</tx:advice>  
   
<aop:config proxy-target-class="true">  
       <aop:advisor pointcut="execution( * com.zhaozhi.spider.service.service.*.*(..))" advice-ref="txAdvice" />  
</aop:config>
//....

項目中AOP的實例應用