基于 Annotation 的 Spring AOP 权限验证方法的实现
1. 配置 applicationContext
在 Spring 中支持 AOP 的配置非常的简单,只需要在 Spring 配置文件 applicationContext.xml 中添加:
<aop:aspectj-autoproxy/>
同时在 applicationContext.xml 的 schema 中配置:
清单 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
< beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:p = "http://www.springframework.org/schema/p" xmlns:aop = "http://www.springframework.org/schema/aop" xmlns:context = "http://www.springframework.org/schema/context" xmlns:tx = "http://www.springframework.org/schema/tx" xmlns:cache = "http://www.springframework.org/schema/cache" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd"> |
在配置时,我们需要将引用的 jar 包放置在 WEB-INF/lib 目录下面:
需要的 jar 包有
配置这些之后 Spring AOP 就可以开始工作了。
2. 定义 Annotation
首先,我们定义一个常量来表示用户是否登录:
清单 2
1
2
3
4
5
6
|
package com.example.myenum; public enum ISLOGIN { YES, LOGOUT, NO } |
这里也可以选择不使用 enum,UserAccessAnnotation 中的 isLogin() 方法也可以返回整数或 String 类型,返回类型并没有限制。常量定义之后,我们再定义 Annotation,在 UserAccessAnnotation 中定义 isLogin(),表示用户是否已经登录:
清单 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
package com.example.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import com.example.myenum.ISLOGIN; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface UserAccessAnnotation { /** * User has been login or not. * */ ISLOGIN isLogin(); } |
定义好之后,这个 Annoatation 将可以被放置在需要验证用户是否登录的方法前面,就像下面这样:
清单 4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package com.example.aspect; public class OrderAction extends BaseAction{ …… @UserAccessAnnotation(>isLogin=ISLOGIN.YES) public String Order(){ try{ Boolean result = orderService.order(Quote quote); if(result) return SUCCESS; }catch(Exception e) { logger.debug(e); this.addActionError(getText("user_no_permission_error")); } return INPUT; } …… } |
在这里我们使用 UserAccessAnnotation 来表示需要在 Order 方法执行之前判断用户是否已经登录,如果没有登录,在 struts2 中,通过下面定义的 Exception 的捕获机制,将页面转到登录页面。
3. 在 applicationContext.xml 中定义 Aspect
清单 5
1
2
3
|
< bean id = "permission" class = "com.example.aspect.PermissionAspect" scope = "prototype" > < property name = "authService" ref = "AuthService" /> </ bean > |
我们要在 Spring 中定义 PermissionAspect。在 Struts+Spring 架构中可以把 Aspect 看作是一个 Action,只不过 Aspect 是其他 Action 的前提条件或者结束动作。Aspect 定义中的 Service 属性和 Action 中的 Service 属性没有任何区别。这里我们用 AuthService 类来实现判断用户是否已经登录的逻辑。
4. 定义 PointCut
清单 6
1
2
3
4
5
6
7
8
9
10
|
@Aspect public class SystemArchitecture { /** * A Join Point is defined in the action layer where the method needs * a permission check. */ @Pointcut("@annotation(com.example.annotation.UserAccessAnnotation)") public void userAccess() {} } |
PointCut 即切入点,就是定义方法执行的点,before、after 或者 around。 一般情况下,我们把 PointCut 全部集中定义在 SystemArchitecture 类中,以方便修改和管理。
当实现 Aspect 时可以很方便的使用我们在 SystemArchitecture 中定义的 PointCut。
5. 实现 Aspect
清单 7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
package com.example.aspect; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import com.example.annotation.UserAccessAnnotation; import com.example.base.action.BaseAction; import com.example.myenum.USERTYPE; import com.example.service.AuthService; @Aspect public class PermissionAspect extends BaseAction{ …… AuthService authService = null; @Before(value="com.example.aspect.SystemArchitecture.userAccess()&&"+ "@annotation(userAccessAnnotation)",argNames="userAccessAnnotation") public void checkPermission(UserAccessAnnotation userAccessAnnotation) throws Exception{ IsLogin isLogin = userAccessAnnotation.isLogin (); if(!authService.userLogin(user).equals(isLogin.toString())){ throw new NoPermissionException(getText("user_no_permission_error")); } } …… } |
在 checkPermission 方法前,我们首先定义 PointCut:
1
2
|
@Before(value="com.example.aspect.SystemArchitecture.userAccess()&&"+ "@annotation(userAccessAnnotation)",argNames="userAccessAnnotation"). |
argNames="userAccessAnnotation" 的意思是把 Annotation 当做参数传递进来,并判断用户登录状态是否与 Annotation 中的定义一致。如果不一致,就要抛出 NoPermissionException,通知系统该用户没有权限。
基于 Annotation 的 Spring AOP 权限验证方法的实现的更多相关文章
- 基于 Annotation 拦截的 Spring AOP 权限验证方法
基于 Annotation 拦截的 Spring AOP 权限验证方法 转自:http://www.ibm.com/developerworks/cn/java/j-lo-springaopfilte ...
- Spring学习笔记之四----基于Annotation的Spring AOP编程
你能使用@Aspect annotation将某个Java类标注为Aspect,这个Aspect类里的所有公有方法都可以成为一个Advice,Spring提供了5个Annotation去将某个方法标注 ...
- 基于注解的Spring AOP的配置和使用
摘要: 基于注解的Spring AOP的配置和使用 AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不 ...
- 基于注解的Spring AOP示例
基于注解的Spring AOP示例 目录 在XML配置文件中开启 @AspectJ 支持 声明切面及切入点 声明通知 测试 结语 在XML配置文件中开启 @AspectJ 支持 要使用Spring的A ...
- 基于注解的Spring AOP的配置和使用--转载
AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...
- 基于@AspectJ配置Spring AOP之一--转
原文地址:http://tech.it168.com/j/2007-08-30/200708302209432.shtml 概述 在低版本Spring中定义一个切面是比较麻烦的,需要实现特定的接口,并 ...
- Spring学习总结(17)——Spring AOP权限管理
每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就 ...
- Asp.net Mvc4 基于Authorize实现的模块权限验证方式
在MVC中,我们可以通过在action或者controller上设置Authorize[Role="xxx"] 的方式来设置用户对action的访问权限.显然,这样并不能满足我们的 ...
- Spring AOP项目应用——方法入参校验 & 日志横切
转载:https://blog.csdn.net/Daybreak1209/article/details/80591566 应用一:方法入参校验 由于系统多个方法入参均对外封装了统一的Dto,其中D ...
随机推荐
- SQL Server中将多行数据拼接为一行数据并且有特殊字符
有表结构如下: 这时,要求显示所有学生的爱好的结果集,代码如下: ) as hobby FROM ( SELECT name, (SELECT hobby+',' FROM student WHERE ...
- 使用ubuntu搭建时间机器备份服务
如何在ubuntu下搭建时间备份服务 折腾了很久,终于可以了. 请严格按照下面的方式来操作. 真正明白问题的,可以按照自己的思路来. 我用的是ubnutu 16.04 安装配置netatalk sud ...
- ie兼容placeholder效果
转载:http://www.jb51.net/article/56244.htm placeholder是HTML5<input>的属性之一,在不同的浏览器( 支持HTML5的现代浏览器 ...
- 201621123023《Java程序设计》第11周学习总结
一.本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 二.书面作业 本次PTA作业题集多线程 1. 源代码阅读:多线程程序BounceThread 1.1 BallRun ...
- GO学习笔记 - 数据类型推导
官方教程:https://tour.go-zh.org/basics/14 在定义一个变量却并不显式指定其类型时(使用 := 语法或者 var = 表达式语法), 变量的类型由(等号)右侧的值推导得出 ...
- vsftpd服务器配置虚拟用户
添加宿主用户 新建系统用户vsftpd,用户目录为/home/wwwroot, 用户登录终端设为/bin/false(即使之不能登录系统) useradd vsftpd -d /home/wwwroo ...
- 使用python 模仿mybinlog 命令 二进制分析mysql binlog
出处:黑洞中的奇点 的博客 http://www.cnblogs.com/kelvin19840813/ 您的支持是对博主最大的鼓励,感谢您的认真阅读.本文版权归作者所有,欢迎转载,但请保留该声明. ...
- 开源单点登录系统CAS入门
一.什么是CAS CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目.CAS 具有以 ...
- c语言中变量/函数命名以单下划线(_)和双下划线(__) 开头的意义
以单下划线(_)表明是标准库的变量 双下划线(__) 开头表明是编译器的变量 建议自己在命名的时候不要用下划线开头,避免与标准库中的命名冲突 命名方法有好多,何必为自己找不自在呢.
- 蓝桥杯-学霸的迷宫(BFS+记录操作)
算法提高 学霸的迷宫 时间限制:1.0s 内存限制:256.0MB 问题描述 学霸抢走了大家的作业,班长为了帮同学们找回作业,决定去找学霸决斗.但学霸为了不要别人打扰,住在一个城堡 ...