利用基于@AspectJ的AOP实现权限控制
一. AOP与@AspectJ
AOP 是 Aspect Oriented Programming 的缩写,意思是面向方面的编程。我们在系统开发中可以提取出很多共性的东西作为一个 Aspect,可以理解为在系统中,我们需要很多次重复实现的功能。比如计算某个方法运行了多少毫秒,判断用户是不是具有访问权限,用户是否已登录,数据的事务处理,日志记录等等。
AOP的术语
- 连接点(Joinpoint)
程序执行的某个特殊位置:比如类开始初始化前,类初始化后,某个方法调用前,调用后等。 连接点 可 以 理解为AOP向目标类织入代码的地方。
- 切点(Pointcut)
每一个类都有许多的连接点,所以AOP通过切点来定位特定的连接点。可以通过数据库查询的概念来理解切点和连接点的关系:连接点相当于数据库中的记录,而切点就是查询条件。切点和连接点不是一对一的关系,一个切点可以匹配多个连接点。
- 增强(Advice)
增强就是织入到目标类连接点上的一段代码。它既包含了添加到目标连接点上的一段执行逻辑,也包含了用于定位连接点的方位信息。
AspectJ是语言级的AOP实现,它扩展了AOP的语法,能够在编辑提供横切代码的织入。@AspectJ是AspecJ1.5新增的功能,它通过JDK5.0的注解技术,允许开发者在POJO中定义切面。
二. 自定义注解
因为@AspectJ是基于JDK5.0的注解技术实现,所以我们有必要了解一下注解相关的知识,并学习如何自定义一个注解。
注解(Annotation)是代码的附属信息,它可以用来修饰类,属性,方法,同时它遵循一个基本原则,注解不能直接干扰程序代码的运行,无论是增加或者删除注解,代码都能正常运行。
(1)一个简单的注解类
Java规定使用@interface修饰定义的注解类。一个注解类可以拥有多个成员,成员声明和接口方法声明类似。
1: package com.wbl.aop;
2:
3: import java.lang.annotation.ElementType;
4: import java.lang.annotation.Retention;
5: import java.lang.annotation.RetentionPolicy;
6: import java.lang.annotation.Target;
7:
8: /**
9: * Created by Lulala on 2015/7/15.
10: */
11: @Retention(RetentionPolicy.RUNTIME) //声明注解的保留期限
12: @Target(ElementType.METHOD) //声明可以使用该注解的目标类型
13: public @interface UserAccessAnnotation { //定义注解
14: ACCESS value() default ACCESS.LOOK; //声明注解成员
15: }
三. @AspectJ的使用
Spring采用AspectJ提供的@AspectJ注解类库及相应的解析库,所以需要在项目中导入aspectjweaver.jar类包。
(1)定义一个切面
1: import org.aspectj.lang.annotation.Aspect;
2: import org.aspectj.lang.annotation.Before;
3: @Aspect //通过注解将AspectTest标识为一个切面
4: public class AspectTest{
5: @Before("execution(* set(..))") //定义切点和增强类型
6: public void before(){ //增强的横切逻辑
7: System.out.println("Aspect before");
8: }
9: }
首先,在AspectTest类的定义处,标注了一个@Aspect的注解,表示这个类是一个切面,其次在before方法定义处,标注了@Before注解,并为该注解提供了成员值"execution(* set(..))"。@Before注解表示该增强是前置增强,成员值是一个切点表达式,表示在目标类的set方法上织入增强。
(2)通过配置使用@AspectJ切面
1: <beans xmlns="http://www.springframework.org/schema/beans"
2: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3: xmlns:p="http://www.springframework.org/schema/p"
4: xmlns:context="http://www.springframework.org/schema/context"
5: xmlns:aop="http://www.springframework.org/schema/aop"
6: xsi:schemaLocation="http://www.springframework.org/schema/beans
7: http://www.springframework.org/schema/beans/spring-beans.xsd
8: http://www.springframework.org/schema/context
9: http://www.springframework.org/schema/context/spring-context-3.0.xsd
10: http://www.springframework.org/schema/aop
11: http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
12:
13: <aop:aspectj-autoproxy/>
14: <bean class="com.wbl.AspectTest"/>
首先,在配置文件中引入aop的命名空间,然后通过aop命名空间的<aop:aspectj-autoproxy/>自动为Spring容器中那些匹配@AspectJ切面的Bean创建代理,完成自动代理的创建工作。
<aop:aspectj-autoproxy/>有一个proxy-target-class属性,默认为false,表示使用JDK的动态代理织入增强,当配置为<aop:aspectj-autoproxy proxy-target-class=”true”/>时,表示使用CGLib的动态代理织入增强。
四. 利用基于@AspectJ的AOP实现权限控制
(1) 定义一个枚举类
1: public enum ACCESS {
2: LOOK,EXIT,DOWNLOAD,ADMIN
3: }
该枚举表示用户拥有的权限,权限由低到高。
(2)定义一个注解
1: @Retention(RetentionPolicy.RUNTIME) //声明注解的保留期限
2: @Target(ElementType.METHOD) //声明可以使用该注解的目标类型
3: public @interface UserAccessAnnotation { //定义注解
4: ACCESS value() default ACCESS.LOOK; //声明注解成员
5: }
定义好这个注解之后,可以把注解放在需要进行权限控制的方法前
1: public class DataOperate extends ActioinSupport{
2:
3: @UserAccessAnnotation(ACCESS.ADMIN)
4: public String updateData(String data){
5: System.out.println("Updata Data");
6: }
7: }
在这里我们使用 UserAccessAnnotation 来表示需要在updateData 方法执行之前判断用户的权限是否为管理员权限。
(3) 定义切点Pointcut
1: public class SystemArchitecture {
2: /**
3: * A Join Point is defined in the action layer where the method needs
4: * a permission check.
5: */
6: @Pointcut("@annotation(com.wbl.aop.UserAccessAnnotation)")
7: public void userAccess(){}
8: }
PointCut 即切入点,就是定义方法执行的点,before表示在方法执行前、after 表示方法执行后或者 around表示方法执行前后。 一般情况下,我们把 PointCut 全部集中定义在 SystemArchitecture 类中,以方便修改和管理。
(4) 定义一个切面
1: @Aspect
2: public class PermissionAspect {
3: @Before(value = "com.wbl.aop.SystemArchitecture.userAccess()&&" +
4: "@annotation(userAccessAnnotation)",argNames="userAccessAnnotation")
5:
6: public void checkPermission(UserAccessAnnotation userAccessAnnotation) throws Exception{
7: User user = (User)ActionContext.getContext().getSession().get("user");
8: if(user != null){
9: if(user.getBehaviorLevel() < userAccessAnnotation.value().ordinal() + 1){
10: throw new NoPermissionException("NO_ACCESS");
11: }
12: }
13: }
14: }
argNames="userAccessAnnotation" 的意思是把 Annotation 当做参数传递进来,并判断用户的权限是否足够。如果用户的权限不足以访问该方法,就要抛出 NoPermissionException,通知系统该用户没有权限。其中NoPermissionException是自定义的异常。
1: public class NoPermissionException extends Exception {
2: public NoPermissionException(String msg){
3: super(msg);
4: }
5: }
(5) 在applicationContext.xml中配置切面
1: <aop:aspectj-autoproxy/>
2: <bean class="com.wbl.aop.PermissionAspect"/>
(6) 在Struts中配置全局异常
1: <global-results>
2: <result name="error">/WEB-INF/jsp/error.jsp</result>
3: </global-results>
4: <global-exception-mappings>
5: <exception-mapping exception="com.wbl.exceptions.NoPermissionException"
6: result="loginerror"/>
7: </global-exception-mappings>
利用基于@AspectJ的AOP实现权限控制的更多相关文章
- 基于Vue实现后台系统权限控制
原文地址:http://refined-x.com/2017/08/29/基于Vue实现后台系统权限控制/,转载请注明出处. 用Vue/React这类双向绑定框架做后台系统再适合不过,后台系统相比普通 ...
- Spring 基于 AspectJ 的 AOP 开发
Spring 基于 AspectJ 的 AOP 开发 在 Spring 的 aop 代理方式中, AspectJ 才是主流. 1. AspectJ 简介 AspectJ 是一个基于 java 语言的 ...
- [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.
前言: 在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习 ...
- 基于资源名的MVC权限控制
在程序复杂程度不断上升的过程中,无可避免需要触碰到权限控制,而权限控制又与业务逻辑紧紧相关,市场上出现了大量的权限控制产品,而程序的开发,讲究去繁化简的抽象,在我的开发过程中,逐渐发现程序的权限控制核 ...
- 基于RESTful API 设计用户权限控制
RESTful简述 本文是基于RESTful描述的,需要你对这个有初步的了解. RESTful是什么? Representational State Transfer,简称REST,是Roy Fiel ...
- 基于原生PHP交叉会员权限控制
对于一个网站的后台管理系统,单一的超级管理员权限往往不能满足我们的需求,尤其是对于大型网站而言,这种单一的权限会引发许许多多的问题出现. 比如:一个网站编辑,平时他只是负责公司网站的公告更新,但如果网 ...
- aop (权限控制之功能权限)
在实际web开发过程中通常会存在功能权限的控制,不如这个角色只允许拥有查询权限,这个角色拥有CRUD权限,当然按钮权限显示控制上可以用button.tld来控制,本文就不说明. 具体控制流程就是通过登 ...
- aop(权限控制)
创建sysContext (管理请求) package com.tp.soft.common.util; import javax.servlet.http.HttpServletRequest; i ...
- Spring基于AspectJ的AOP的开发——注解
源码:https://gitee.com/kszsa/dchart 一, AspectJ的概述: AspectJ是一个面向切面的框架,它扩展了Java语言.AspectJ定义了AOP语法所以它有一个专 ...
随机推荐
- 级联MobileNet-V2实现CelebA人脸关键点检测(转)
https://blog.csdn.net/u011995719/article/details/79435615
- 指定网卡进行ping操作
windows系统下:ping -S 查看当前网卡情况 ipconfig 有两块网卡,ip分别为 192.168.12.83.192.168.1.126 使用不同网卡分别ping百度 网卡1: pi ...
- Firebug 的脚本页面不能用
1.遇到这种情况,一般重置firebug,然后开启“脚本“功能,刷新页面,就能显示正常 2.要不就是 版本问题,50.0不行,下载回49版本就可以了
- 关于在项目中遇到MySQL数据库死锁的问题
在MySQL中, 当一个事务去更新某条数据, 还没有提交的时候, 第二个事务去更新该数据, 则会出现等待获取锁超时异常: >> Lock wait timeout exceeded; tr ...
- How Many Boyfriends
知乎上看到一个问题,如果一个女人说自己集齐了12个星座的男朋友,那么她已经搞过多少男人了. 先考虑这个问题的最简单版本,如果说该女人每一次和12个星座的男人交往的概率相同. 考虑$dp$ 注意到这个问 ...
- HDU-2553
N皇后问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- aria2安装webui
安装aria2 yum install aria2 安装完成后可以使用简单命令进行下载 aria2c http://example.org/mylinux.iso aria2c -c -s http: ...
- 使用vs2019进行Linux远程开发
通常,当我们开发Linux程序时有两种方案: 在Linux上直接编写程序并进行运行测试和调试 在Windows或Mac OS X上借助工具进行远程开发 虽然我自己是在Linux环境上直接进行开发的,但 ...
- Lightoj1002 【搜索】
题意: 两两之间的点的花费就是:从A点到B的一条路上某段的最大权值:给一个起点,求到各起点的最小花费. 思路: 一开始的思路: n不是才500,我先建个图,然后DFS一下,不对,是2500: 如果直接 ...
- P3803 【模板】多项式乘法(NTT)
传送门 NTT好像是比FFT快了不少 然而感觉不是很看得懂……主要是点值转化为系数表示那里…… upd:大概已经搞明白是个什么玩意儿了……吧…… //minamoto #include<bits ...