面向切面編程(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; } }