SpringBoot AOP攔截

攔截指定的Controller裏面的方法

能夠在指定攔截的Controller中方法執行以前,進行請求攔截,好比對一些須要受權驗證的方法進行攔截判斷cookie及權限。redis

@Aspect @Component數據庫

@Pointcut("execution(public * com.xxx.controller.*.*(..))" +
            "&& !execution(public * com.xxx.controller.WelcomeController.*(..))")
    public void verify() {
    }

    @Before("verify()")
    public void doVerify(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 用戶身份認證
        UserVO user = UserAuth.getUserInfoFromToken(request, redisClient, authService);
        // 同步用戶信息到 threadlocal
        ThreadLocalUtil.set(CommonConstant.USERID, user.getId());
        ThreadLocalUtil.set(CommonConstant.USERNAME, user.getName());

        // 用戶鑑權
        RequestPermissions permissions = UserPermission.getAnnotation(joinPoint);
        if (null != permissions) {
            UserPermission.checkUserPermissionAllow(request, authService, user, permissions);
        }
    }

攔截全部打上指定註解的方法

好比在程序中控制讀寫分離,能夠定義一個@Slave註解,在執行指定service的方法以前判斷是否存在@Slave註解。cookie

@Before("@annotation(test)")// 攔截被TestAnnotation註解的方法;若是你須要攔截指定package指定規則名稱的方法,能夠使用表達式execution(...),具體百度一下資料一大堆
 public void beforeTest(JoinPoint point, TestAnnotation test) throws Throwable {
  System.out.println("beforeTest:" + test.name());
 }
 
 @After("@annotation(test)")
 public void afterTest(JoinPoint point, TestAnnotation test) {
  System.out.println("afterTest:" + test.name());
 }

    @Around("@annotation(slave)")
    public Object proceed(ProceedingJoinPoint proceedingJoinPoint, Slave slave) throws Throwable {
        try {
            logger.info("set database connection to slave");
            DatabaseContextHolder.setDatabaseType(DatabaseType.SLAVE);
            return proceedingJoinPoint.proceed();
        } finally {
            DatabaseContextHolder.clearDbType();
            logger.info("restore database connection");
        }
    }

攔截dao數據庫操做方法,作讀寫分離

@Aspect
@Component
public class DataSourceAspect {
 
    @Before("execution(* com.xxx.firstboot.dao.*.*(..))")
    public void setDataSourceKey(JoinPoint point){
         //鏈接點所屬的類實例是ShopDao
         if(point.getTarget() instanceof ShopDao){
             DatabaseContextHolder.setDatabaseType(DatabaseType.mytestdb2);
         }else{//鏈接點所屬的類實例是UserDao(固然,這一步也能夠不寫,由於defaultTargertDataSource就是該類所用的mytestdb)
             DatabaseContextHolder.setDatabaseType(DatabaseType.mytestdb);
         }
     }

}
相關文章
相關標籤/搜索