面向切面编程(AOP)是Spring的两大核心之一.AOP的思想能够帮助咱们在不侵入代码的状况下对原有功能进行加强,修改;编程
反射 -> proxy(动态代理) -> AOP(面向切面)api
@Aspect * 定义切面类 @Pointcut * 切点 Advice * 在切入点上执行的加强处理 * @Before * @After * @AfterReturning 切点方法拿到返回值后执行 * @AfterThrowing 切点方法抛出异常后执行 * @Around 环绕加强 正常的执行顺序是:@Around ->@Before->主方法体->@Around中pjp.proceed()->@After->@AfterReturning
若是不执行proceedingJoinPoint.proceed()方法,那么目标方法不会执行; 能够决定是否执行目标方法;@before只是拦截方法;若是加了@around,原方法交给proceed()控制 //xx()是切点 @Around("xx()") public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{ log.info("进入around") return proceedingJoinPoint.proceed(); }
spd系统中使用aop对向外提供的api接口进行token校验权限控制.this
1.首先自定义注解并在须要权限认证的接口上加上注解url
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface ReportPermission { }
2.代理
@Component @Aspect @Slf4j public class OrderReportAspect { @Autowired private ISysUserService sysUserService; @Pointcut("@annotation(com.x.common.annotation.ReportPermission)") public void pointCut() {} //根据角色控制容许访问接口的用户 @Around("pointCut()") public Object before(ProceedingJoinPoint pjp) throws Throwable { Object[] in = pjp.getArgs(); if (in.length >= 1) { HttpServletRequest request = (HttpServletRequest) in[0]; log.info("切面获取request:{}",request); String userId = JwtUtil.checkToken(request.getHeader("token")); //校验当前userId是否有读取接口的权限 int count = sysUserService.isSpecified(userId,Constant.LOGISTICS_REPORT_RECEIVER); if (count == 1) {return pjp.proceed();} log.warn("api接口角色校验失败"); return null; } log.warn("api接口角色校验失败"); return null; } }