【sping揭秘】12、SpringAOP的实现机制
SpringAOP的实现机制
设计模式代理模式
参考我之前的代理模式
http://www.cnblogs.com/cutter-point/p/5226642.html
这里写个简单的案例
package spring.aop.designPattern; /**
*
* Title: ISubject.java
* Description:代理模式的资源接口类
* @author xiaof
* @date 2018年4月7日
* @version 1.0
*
*/
public interface ISubject { public void request();
}
package spring.aop.designPattern; /**
*
* Title: SubjectImpl.java
* Description: 被访问者,或者被访问的资源实现类
* @author xiaof
* @date 2018年4月7日
* @version 1.0
*
*/
public class SubjectImpl implements ISubject { @Override
public void request() {
// TODO Auto-generated method stub
System.out.println("this is subjectImpl cutter_point ! ");
} }
package spring.aop.designPattern; /**
*
* Title: SubjectProxy.java
* Description: 代理实现类
* @author xiaof
* @date 2018年4月7日
* @version 1.0
*
*/
public class SubjectProxy implements ISubject { private ISubject subject; @Override
public void request() {
System.out.println("pre operation subjectproxy");
if(subject != null)
subject.request(); System.out.println("after operation subjectproxy");
} public ISubject getSubject() {
return subject;
} public void setSubject(ISubject subject) {
this.subject = subject;
} }
package spring.aop.designPattern; import org.junit.Test; public class Main { @Test
public void test1() {
SubjectImpl si = new SubjectImpl();
SubjectProxy sp = new SubjectProxy();
sp.setSubject(si); sp.request();
}
}
测试一波:
这就是,比如我们要对subjectimpl进行代理的时候,我们就需要根据ISubject接口实现一个代理类对象
好,基于此点,
缺点1:如果我们一个类不存在接口类型,并且是第三方的类对象,比如我们现在有一个subjectimpl2,这个类没有实现ISubject接口,那么我们的subjectimpl还能进行代理吗?显然是不能的
缺点2:我们发现对一个subjectimpl对象进行代理就要实现一个代理类subjectProxy,那如果我们项目用有一个万类对象需要进行代理,那么我们需要创建一万个proxy类,好吧,我反正会疯的。。。
动态代理
这个jdk的动态代理主要是,proxy类和invocationhandler接口
package spring.aop.designPattern; /**
*
* Title: ISubject.java
* Description:代理模式的资源接口类
* @author xiaof
* @date 2018年4月7日
* @version 1.0
*
*/
public interface ISubject { public void request();
}
package spring.aop.designPattern; /**
*
* Title: SubjectImpl.java
* Description: 被访问者,或者被访问的资源实现类
* @author xiaof
* @date 2018年4月7日
* @version 1.0
*
*/
public class SubjectImpl implements ISubject { @Override
public void request() {
// TODO Auto-generated method stub
System.out.println("this is subjectImpl cutter_point ! ");
} }
代理类
package spring.aop.dynamicPorxy; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Date; import spring.aop.util.DateUtil; /**
*
* Title: RequestCtrlInvocationHandler.java
* Description: jdk动态代理对象
* @author xiaof
* @date 2018年4月7日
* @version 1.0
*
*/
public class RequestCtrlInvocationHandler implements InvocationHandler { /**
* 代理对象
*/
private Object target;
/**
* 00:00:00
*/
private String beginTime;
/**
* 00:00:00
*/
private String endTime; public RequestCtrlInvocationHandler(Object target, String beginTime, String endTime) {
this.target = target;
this.beginTime = beginTime;
this.endTime = endTime;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//判断是否是request方法,如果是进行拦截操作
if(method.getName().equals("request")) {
//判断当前时间是否在区间内,如果是,那么就进行相应的操作
if(DateUtil.isInDate(new Date(), beginTime, endTime)) {
System.out.println("区间内时间,拦截成功");
return method.invoke(target, args);
} else {
System.err.println("区间外时间");
return null;
}
}
return method.invoke(target, args);
} }
最后测试:
目前时间!
那么我们修改时间区间,看是否会产生不一样的后果!!!
0-12点
那么我们把时间改为22点呢
拦截成功
不多BB,这个还是有问题,无法处理接口类问题
动态字节码生成
使用cblib
package spring.aop.cglib; import java.lang.reflect.Method;
import java.util.Date; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy; import spring.aop.util.DateUtil; /**
*
* Title: RequestCtrlCallback.java
* Description: 动态字节码技术
* @author xiaof
* @date 2018年4月7日
* @version 1.0
*
*/
public class RequestCtrlCallback implements MethodInterceptor { private static final Log logger = LogFactory.getLog(RequestCtrlCallback.class); /**
* 00:00:00
*/
private String beginTime;
/**
* 00:00:00
*/
private String endTime; public RequestCtrlCallback(String beginTime, String endTime) {
this.beginTime = beginTime;
this.endTime = endTime;
} @Override
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { //如果是我们需要拦截的方法,那么进行相应的操作
if(arg1.getName().equals("request")) {
if(DateUtil.isInDate(new Date(), beginTime, endTime)) {
//在对应的时间区间内,成功
logger.info("成功拦截到对应的区间,放行!");
return arg3.invokeSuper(arg0, arg2);
} else {
logger.error("错误时间区间!!");
return null;
}
} return arg3.invokeSuper(arg0, arg2); } public String getBeginTime() {
return beginTime;
} public void setBeginTime(String beginTime) {
this.beginTime = beginTime;
} public String getEndTime() {
return endTime;
} public void setEndTime(String endTime) {
this.endTime = endTime;
} }
package spring.aop.cglib; import org.junit.Test;
import org.springframework.cglib.proxy.Enhancer; import spring.aop.designPattern.SubjectImpl; public class Main { @Test
public void test1() {
//使用cglib代理对象
String beginTime = "00:00:00";
String endTime = "20:00:00";
Enhancer enhancer = new Enhancer();
//设置代理类对象
enhancer.setSuperclass(SubjectImpl.class); enhancer.setCallback(new RequestCtrlCallback(beginTime, endTime)); //生成代理对象
SubjectImpl proxyObj = (SubjectImpl) enhancer.create(); proxyObj.request();
}
}
结果展示:
【sping揭秘】12、SpringAOP的实现机制的更多相关文章
- 【sping揭秘】11、Java 平台上的AOP实现机制
动态代理 Jdk1.3只有引入的动态代理机制,可以再运行期间,为相应的接口(必须得有接口)动态生成对应的代理对象 基于以上问题,我们可以将横切关注点逻辑封装到动态代理的invocationhandle ...
- Mac OS 10.12 - 如何关闭Rootless机制?
一,进入恢复模式(Recovery):具体操作方法参见下面这篇博客: http://www.cnblogs.com/sunylat/p/6414697.html 二,关闭Rootless机制 1,选择 ...
- 云计算和大数据时代网络技术揭秘(十七)VOQ机制
VOQ机制 本章介绍的VOQ是一种新型的QoS机制,目的是为了解决著名的交换机HoL难题. 但VOQ强烈依赖于调度算法,例如,一个48口的交换机,每个端口都要维护48-1个FIFO缓存队列, 一共48 ...
- [转]NHibernate之旅(12):初探延迟加载机制
本节内容 引入 延迟加载 实例分析 1.一对多关系实例 2.多对多关系实例 结语 引入 通过前面文章的分析,我们知道了如何使用NHibernate,比如CRUD操作.事务.一对多.多对多映射等问题,这 ...
- 【sping揭秘】22、事务管理
有关事务的楔子 什么是事务??? 事务就是以可控的方式对数据资源进行访问的一组操作. 事务本身持有四个限定属性 原子性,一致性,隔离性,持久性 事务家族 Resource Manager RM,负责 ...
- 带你入门代理模式/SpringAop的运行机制
SpringAop 是spring框架中最重要的一项功能之一,同时也是企业级开发记录事物日志等不可或缺的一部分,如果说你的系统需要记录用户访问接口的操作,那SpringAop是很完美的了,当然,拦截器 ...
- 12.java中参数传递机制---形参和实参
1.形参:用来接收调用该方法时传递的参数.只有在被调用的时候才分配内存空间,一旦调用结束,就释放内存空间.因此仅仅在方法内有效. public void swap(int a, int b) { in ...
- 【sping揭秘】25、Spring远程方案
分化:RMI,EJB,Hessian Spring有 Rmi,http,hessian,burlap 基于rmi的remoting方案 RMI要求远程类对象包路径和本地一致 基于HTTP的轻量级rem ...
- 【sping揭秘】24、Spring框架对JMS的集成(无环境版,以后学MQ的时候再隆重介绍)& 任务调度和线程池
这个我也不是很了解,那么这个需要好好学习一下了 JMS有2种消息域类型 1. point to point 点对点模式 2.发布订阅模式 publish/subscribe Pub/Sub 模式 传 ...
随机推荐
- dj forms表单组件
手动的一个个去校验前端传过来的字段数据,是很麻烦的,利用django 的forms组件,对需要校验的字段定义好,能够大大提高效率. 校验字段功能 from django.db import model ...
- 容器,表格 ,div,元素可左右拖动,滚动 css
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- 2.2.1synchronized方法的弊端
缺陷:用关键字synchronized声明方法是有弊端的,譬如A线程调用同步方法执行一个长时间的任务,那么B线程则必须等待较长的时间, 解决方法:使用synchronized同步语句块 package ...
- Northwind测试学习用数据库
下载地址: https://northwinddatabase.codeplex.com/
- iOS中的序列帧动画
UIImageView对象的有一个animationImages属性,将图片数组赋值给该属性即可.如图: 控制动画的播放方法是:[ ___ startAnimating]; 控制动画的停止方法是:[ ...
- 12.equals()方法总结
超类Object中有这个equals()方法,该方法主要用于比较两个对象是否相等.该方法的源码如下: 我们知道所有对象都有表示(内存地址)和状态(数据),看上面代码是用"=="来比 ...
- hdu 5092 线裁剪(纵向连线最小和+输出路径)
http://acm.hdu.edu.cn/showproblem.php?pid=5092 给一个m*n的矩阵,找到一个纵向的"线"使得线上的和最小并输出这条线,线能向8个方向延 ...
- Android-Throwable: A WebView method was called on thread 'JavaBridge'.
错误详情: 01-30 03:36:52.441 12000-12048/cn.h5 D/@@@: e.ttt:java.lang.RuntimeException: java.lang.Throwa ...
- HTML超级链接详细讲解
超级链接是网站中使用比较频繁的HTML元素,因为网站的各种页面都是由超级链接串接而成,超级链接完成了页面之间的跳转.超级链接是浏览者和服务器的交互的主要手段,在后面的技术中会逐步深化学习. — 注意 ...
- Markdown中怎么上传图片
在网站中使用了Markdown编辑器,但是不能支持图片的直接粘贴