Spring AOP 本质(3)
public class Action {
public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm, ServletRequest servletRequest, ServletResponse servletResponse) throws java.lang.Exception { /* compiled code */ }
public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm, http.HttpServletRequest httpServletRequest, http.HttpServletResponse httpServletResponse) throws java.lang.Exception { /* compiled code */ }
....
}
public ActionForward real(ActionMapping actionMapping, ActionForm actionForm, http.HttpServletRequest httpServletRequest, http.HttpServletResponse httpServletResponse)throws java.lang.Exception;
作为业务请求处理的方法,放到重写的execute方法内部调用。
public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm, http.HttpServletRequest httpServletRequest, http.HttpServletResponse httpServletResponse) throws java.lang.Exception {
//todo: 安全检查逻辑
return real(actionMapping,actionForm,httpServletRequest,httpServletResponse);
}
public abstract ActionForward real(ActionMapping actionMapping, ActionForm actionForm, http.HttpServletRequest httpServletRequest, http.HttpServletResponse httpServletResponse) throws java.lang.Exception;
}
public abstract ActionForward real(ActionMapping actionMapping, ActionForm actionForm, http.HttpServletRequest httpServletRequest, http.HttpServletResponse httpServletResponse) throws java.lang.Exception{
//todo: 单纯处理实际的业务请求
return ...
}
....
}
* 用户登录信息载体
*/
public class UserInfo {
private String userName;
private String password;
public UserInfo(String userName, String password) {
this.userName = userName;
this.password = password;
}
public String getPassword() {
return password;
}
public String getUserName() {
return userName;
}
}
* 业务组件:被代理的对象
*/
public class SecureBean {
/**
* 示范性的业务方法,这个方法将被拦截,加入一些附加逻辑
*/
public void businessOperate() {
System.out.println("业务方法businessOperate()被调用了!");
}
}
* 安全管理类:检查用户登录和管理用户注销登录的业务逻辑。
*/
public class SecurityManager {
//为每一个SecurityManager创建一个本地线程变量threadLocal,用来保存用户登录信息UserInfo
private static ThreadLocal threadLocal = new ThreadLocal();
/**
* 用户登录方法,允许任何用户登录。
* @param userName
* @param password
*/
public void login(String userName, String password) {
// 假定任何的用户名和密码都可以登录
// 将用户登录信息封装为UerInfo对象,保存在ThreadLocal类的对象threadLocal里面
threadLocal.set(new UserInfo(userName, password));
}
public void logout() {
// 设置threadLocal对象为null
threadLocal.set(null);
int x = 0;
}
public UserInfo getLoggedOnUser() {
// 从本地线程变量中获取用户信息UerInfo对象
return (UserInfo) threadLocal.get();
}
}
import org.springframework.aop.MethodBeforeAdvice;
/**
* 前置通知类
*/
public class SecurityAdvice implements MethodBeforeAdvice {
private SecurityManager securityManager;
public SecurityAdvice() {
this.securityManager = new SecurityManager();
}
/**
* 前置通知的接口方法实现。仅允许robh用户登录,强制设定的。
*/
public void before(Method method, Object[] args, Object target)
throws Throwable {
UserInfo user = securityManager.getLoggedOnUser();
if (user == null) {
System.out.println("没有用户凭证信息!,本前置通知仅仅允许robh用户登录,不信你试试看!");
throw new SecurityException(
"你必须在调用此方法" + method.getName() + "前进行登录:");
} else if ("robh".equals(user.getUserName())) {
System.out.println("用户robh成功登录:OK!");
} else {
System.out.println("非法用户"+user.getUserName()+",请使用robh登录,用户调用的方法是:" + method.getName());
throw new SecurityException("用户" + user.getUserName()
+ " 不允许调用" + method.getName() + "方法!");
}
}
}
/**
* 测试类,客户端
*/
public class SecurityExample {
public static void main(String[] args) {
//得到一个 security manager
SecurityManager mgr = new SecurityManager();
//获取一个SecureBean的代理对象
SecureBean bean = getSecureBean();
//尝试用robh登录
mgr.login("robh", "pwd"); //检查登录情况
bean.businessOperate(); //业务方法调用
mgr.logout(); //注销登录
//尝试用janm登录
try {
mgr.login("janm", "pwd"); //检查登录情况
bean.businessOperate(); //业务方法调用
} catch (SecurityException ex) {
System.out.println("发生了异常: " + ex.getMessage());
} finally {
mgr.logout(); //注销登录
}
// 尝试不使用任何用户名身份调用业务方法
try {
bean.businessOperate(); //业务方法调用
} catch (SecurityException ex) {
System.out.println("发生了异常: " + ex.getMessage());
}
}
/**
* 获取SecureBean的代理对象
*
* @return SecureBean的代理
*/
private static SecureBean getSecureBean() {
//创建一个目标对象
SecureBean target = new SecureBean();
//创建一个通知
SecurityAdvice advice = new SecurityAdvice();
//获取代理对象
ProxyFactory factory = new ProxyFactory();
factory.setTarget(target);
factory.addAdvice(advice);
SecureBean proxy = (SecureBean) factory.getProxy();
return proxy;
}
}
用户robh成功登录:OK!
业务方法businessOperate()被调用了!
非法用户janm,请使用robh登录,用户调用的方法是:businessOperate
发生了异常: 用户janm 不允许调用businessOperate方法!
没有用户凭证信息!,本前置通知仅仅允许robh用户登录,不信你试试看!
发生了异常: 你必须在调用此方法businessOperate前进行登录:
Process finished with exit code 0
Spring AOP 本质(3)相关推荐
- Spring AOP本质(7)
Spring AOP本质(7) 上一个里面,给出静态方法切点匹配的例子,现在给出一个动态的实现例子: 没有 /** * 业务组件 */ public class SampleBean { pu ...
- Spring AOP 本质
AOP本质是拦截,拦截的本质是代理,代理分动态和静态,静态代理很简单,功能有限,应用不是很广泛,Spring中主要用的动态代理. 用Spring做开发,AOP的实现仅仅是编程实现一些接口,然后配置 ...
- 《Spring揭秘》读书笔记 2:Spring AOP
7 一起来看AOP 2009年8月,<一起来看流星雨>开播. 2009年9月,<Spring揭秘>出版. 7.1 AOP核心概念 AOP AOP全称为Aspect-Orient ...
- Spring Aop 常见注解和执行顺序
欢迎关注方志朋的博客,回复"666"获面试宝典 来源:juejin.cn/post/7062506923194581029 Spring 一开始最强大的就是 IOC / AOP 两 ...
- 彻底理解Spring AOP
目录 前言 1. AOP概念 2. AOP的实现 3. Spring的IoC理解: 4. Sping知识整理 前言 AOP英文名为Aspect Oriented Programming,意为面向切面编 ...
- (转)Spring AOP的底层实现技术
AOP概述 软件的编程语言最终的目的就是用更自然更灵活的方式模拟世界,从原始机器语言到过程语言再到面向对象的语言,我们看到编程语言在一步步用更自然.更强大的方式描述软件.AOP是软件开发思想的一个飞跃 ...
- Spring AOP中定义切点(PointCut)和通知(Advice)
本文讨论一下Spring AOP编程中的两个关键问题,定义切点和定义通知,理解这两个问题能应付大部分AOP场景. 如果你还不熟悉AOP,请先看AOP基本原理,本文的例子也沿用了AOP基本原理中的例子. ...
- 9000+ 字,彻底征服 Spring AOP ,美滋滋
基本知识 其实, 接触了这么久的 AOP, 我感觉, AOP 给人难以理解的一个关键点是它的概念比较多, 而且坑爹的是, 这些概念经过了中文翻译后, 变得面目全非, 相同的一个术语, 在不同的翻译下, ...
- Spring AOP概述及底层实现原理
Spring AOP概述及底层实现原理 aop概述 AOP全称为Aspect Oriented Programming的缩写,意为:面向切面编程.将程序中公用代码进行抽离,通过动态代理实现程序功能的统 ...
最新文章
- CentOS7(64位)安装NVIDIA显卡驱动和CUDA8.0
- ACM学习历程—Hihocoder [Offer收割]编程练习赛1
- Spring与日志的整合
- php中对ASCII码的处理ord() 、chr()
- 求你了,听我一句劝吧,这几个玩意就别学了!
- 用R语言做数据分析——时间序列分类
- 为什么使用工作流引擎,什么是工作流引擎,工作流引擎选型以及如何使用
- 一个完整的产品设计都要哪些设计流程
- STC8I2CGY-302(BH1750光照度强度模块)
- 租酥雨的NOIP2018赛前日记
- JAVA:实现ClosestPair最近对算法(附完整源码)
- DWcs6+AppServ快速搭建PHP环境
- Web设计网站软件推荐
- 数控铣削图案及编程_数控铣床编程30例带图
- 2021最新 腾讯云从零搭建PHP运行环境
- UE5 官方案例Lyra 全特性详解 10.进度汇报和视频推荐
- 2021-09-12 Autodesk inventor 技巧整理
- nltk离线数据:解决nltk.download()下载错误
- 测试用例设计方法 之【等价类划分法】
- Win7系统配置开机自动连接宽带