拦截指定的Controller里面的方法
可以在指定拦截的Controller中方法执行之前,进行请求拦截,比如对一些需要授权验证的方法进行拦截判断cookie及权限。
@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注解。
@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@Componentpublic 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); } }}