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