面向切面编程(AOP)是Spring的两大核心之一.AOP的思想可以帮助我们在不侵入代码的情况下对原有功能进行增强,修改;
大致是以下流程
反射 -> proxy(动态代理) -> AOP(面向切面)
@Aspect
* 定义切面类
@Pointcut
* 切点
Advice
* 在切入点上执行的增强处理
* @Before
* @After
* @AfterReturning 切点方法拿到返回值后执行
* @AfterThrowing 切点方法抛出异常后执行
* @Around 环绕增强
正常的执行顺序是:@Around ->@Before->主方法体->@Around中pjp.proceed()->@After->@AfterReturning
@Around
如果不执行proceedingJoinPoint.proceed()方法,那么目标方法不会执行;
可以决定是否执行目标方法;@before只是拦截方法;如果加了@around,原方法交给proceed()控制
//xx()是切点
@Around("xx()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
log.info("进入around")
return proceedingJoinPoint.proceed();
}
语法规则
- 支持&&,||,!
- @Pointcut(execution(url)) 指定切面方法
- @Pointcut("@annotation(url)") 自定义注解指定切面方法
- within,this,target...
demo
spd系统中使用aop对向外提供的api接口进行token校验权限控制.
1.首先自定义注解并在需要权限认证的接口上加上注解
@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;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。