一、课程介绍
【课程名称】SpringBoot 2.x 实战仿B站高性能后端项目。
【章节】第三章3.35、3.36、3.37、3.38 SpringAOP切面编程、接口权限控制
【讲师】HELLOSTAR
二、课程内容
1.SpringAOP切面编程
意思为面向切面编程,是一种约定流程的编程。是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
举例说明:
数据库事务操作包括打开连接数据库、执行sql语句、没有异常则提交事务,有异常则回滚事务、关闭数据库。
其中执行sql语句的前后操作都是固定的,属于是约定好的流程,可以作为切面。
**作用:**在程序运行期间,在不修改源码的情况下对方法进行功能增强。
**优势:**减少重复代码,提高开发效率,并且便于维护。
相关术语:
Target(目标对象):代理的目标对象。
Proxy (代理):一个类被 AOP 织入增强后,就产生一个结果代理类。
Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点。
Pointcut(切入点):所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义。
Advice(通知/ 增强):所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。
Aspect(切面):是切入点和通知(引介)的结合。
Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程。spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入。
2.接口权限控制
使用切面编程实现在每次访问接口前判断当前用户是否有权限访问接口。
1.创建切面类
接口上使用了@ApiLimitedRole注解就会触发该切面,在访问接口前先校验用户权限,权限正常则放行,权限不足则报错。
@Aspect表明是切面类
@Order控制加载顺序
@Order(1)
@Component
@Aspect
public class ApiLimitedRoleAspect {
@Autowired
private UserSupport userSupport;
@Autowired
private UserRoleService userRoleService;
//切入点(任何方法中使用了该注解则会进行切入)
@Pointcut("@annotation(com.imooc.bilibili.domain.annotation.ApiLimitedRole)")
public void check(){
}
//目标方法执行前会执行切入方法,注解参数会带过来
@Before("check() && @annotation(apiLimitedRole)")
public void doBefore(JoinPoint joinPoint, ApiLimitedRole apiLimitedRole){
Long userId = userSupport.getCurrentUserId();
List<UserRole> userRoleList = userRoleService.getUserRoleByUserId(userId);
String[] limitedRoleCodeList = apiLimitedRole.limitedRoleCodeList();
Set<String> limitedRoleCodeSet = Arrays.stream(limitedRoleCodeList).collect(Collectors.toSet());
Set<String> roleCodeSet = userRoleList.stream().map(UserRole::getRoleCode).collect(Collectors.toSet());
roleCodeSet.retainAll(limitedRoleCodeSet);
if(roleCodeSet.size() > 0){
throw new ConditionException("权限不足!");
}
}
}
2.创建角色权限注解
@Retention 运行策略(运行时)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
@Component
public @interface ApiLimitedRole {
String[] limitedRoleCodeList() default {};
}
3.接口上使用注解
传入的用户角色权限注解,进入该接口前切面校验是否权限足够。
@ApiLimitedRole(limitedRoleCodeList = {AuthRoleConstant.ROLE_LV0})
@DataLimited
@PostMapping("/user-moments")
public JsonResponse<String> addUserMoments(@RequestBody UserMoment userMoment) throws Exception {
,,,,,,
}
三、课程收获
SpringAOP则是Spring提供的一个标准易用的aop框架,依托Spring的IOC容器,提供了极强的AOP扩展增强能力,对项目开发提供了极大地便利。