基于 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 ...
随机推荐
- WPF XamlObjectWriterException:无法创建未知类型"Grid"
using (FileStream fs = new FileStream("UnitFile/Report2.xaml", FileMode.Open)) { rootEleme ...
- 3. Python的种类
- JavaScript一个页面中有多个audio标签,其中一个播放结束后自动播放下一个,audio连续播放
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- element-ui Table表格结合CheckBox实现单选效果
最近做项目遇到一个需求,需要实现一个表格的单选,由于项目使用的是element-ui.于是去看了表格的文档,确实有单选的方法,但是官方的单选是直接选中表格行,通过颜色来区分 看着效果不明显,实际需要一 ...
- 域名可以解析(ping域名可以获取正确ip),服务器本地telnet 域名+端口 无法连接,通过建立本地虚拟域名指定的方法解决该问题
环境: 服务器A,网管已为A开通外网ip,且设置有映射域名:假如内网ip为172.16.2.6.外网ip为123.123.123.123.域名为test.sstest.com 现象: 服务器A,tel ...
- 找到windows中的环境变量
我的电脑,右击--->属性---->高级系统设置---->高级----->环境变量
- mxonline实战9,我要学习功能块,机构详情展示,收藏功能
对应github地址:第9天 一. 实现我要学习功能
- vue封装插件并发布到npm上
vue封装插件并发布到npm上 项目初始化 首先,要创建项目,封装vue的插件用webpack-simple很合适,vue init webpack-simple 项目名称此命令创建我们的项目的目录, ...
- Linux服务器核心参数配置
使用Linux作为长连接的web服务器时,为了增加服务的容量,以及处理性能,需要修改一些参数. 一.多进程绑定CPU 1.使用taskset命令可以绑定进程到指定CPU,以减少多核CPU环境中,单进程 ...
- 【Python】解析Python的标准数据类型
目录结构: contents structure [-] 数值(Number) 数值类型 类型转化 Python中的Decimal数据类型 Python中的分数 Python中的算术方法 字符串(St ...