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的实现机制的更多相关文章

  1. 【sping揭秘】11、Java 平台上的AOP实现机制

    动态代理 Jdk1.3只有引入的动态代理机制,可以再运行期间,为相应的接口(必须得有接口)动态生成对应的代理对象 基于以上问题,我们可以将横切关注点逻辑封装到动态代理的invocationhandle ...

  2. Mac OS 10.12 - 如何关闭Rootless机制?

    一,进入恢复模式(Recovery):具体操作方法参见下面这篇博客: http://www.cnblogs.com/sunylat/p/6414697.html 二,关闭Rootless机制 1,选择 ...

  3. 云计算和大数据时代网络技术揭秘(十七)VOQ机制

    VOQ机制 本章介绍的VOQ是一种新型的QoS机制,目的是为了解决著名的交换机HoL难题. 但VOQ强烈依赖于调度算法,例如,一个48口的交换机,每个端口都要维护48-1个FIFO缓存队列, 一共48 ...

  4. [转]NHibernate之旅(12):初探延迟加载机制

    本节内容 引入 延迟加载 实例分析 1.一对多关系实例 2.多对多关系实例 结语 引入 通过前面文章的分析,我们知道了如何使用NHibernate,比如CRUD操作.事务.一对多.多对多映射等问题,这 ...

  5. 【sping揭秘】22、事务管理

    有关事务的楔子 什么是事务??? 事务就是以可控的方式对数据资源进行访问的一组操作. 事务本身持有四个限定属性 原子性,一致性,隔离性,持久性 事务家族 Resource Manager  RM,负责 ...

  6. 带你入门代理模式/SpringAop的运行机制

    SpringAop 是spring框架中最重要的一项功能之一,同时也是企业级开发记录事物日志等不可或缺的一部分,如果说你的系统需要记录用户访问接口的操作,那SpringAop是很完美的了,当然,拦截器 ...

  7. 12.java中参数传递机制---形参和实参

    1.形参:用来接收调用该方法时传递的参数.只有在被调用的时候才分配内存空间,一旦调用结束,就释放内存空间.因此仅仅在方法内有效. public void swap(int a, int b) { in ...

  8. 【sping揭秘】25、Spring远程方案

    分化:RMI,EJB,Hessian Spring有 Rmi,http,hessian,burlap 基于rmi的remoting方案 RMI要求远程类对象包路径和本地一致 基于HTTP的轻量级rem ...

  9. 【sping揭秘】24、Spring框架对JMS的集成(无环境版,以后学MQ的时候再隆重介绍)& 任务调度和线程池

    这个我也不是很了解,那么这个需要好好学习一下了 JMS有2种消息域类型 1. point to point 点对点模式 2.发布订阅模式  publish/subscribe Pub/Sub 模式 传 ...

随机推荐

  1. dj forms表单组件

    手动的一个个去校验前端传过来的字段数据,是很麻烦的,利用django 的forms组件,对需要校验的字段定义好,能够大大提高效率. 校验字段功能 from django.db import model ...

  2. 容器,表格 ,div,元素可左右拖动,滚动 css

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  3. 2.2.1synchronized方法的弊端

    缺陷:用关键字synchronized声明方法是有弊端的,譬如A线程调用同步方法执行一个长时间的任务,那么B线程则必须等待较长的时间, 解决方法:使用synchronized同步语句块 package ...

  4. Northwind测试学习用数据库

    下载地址: https://northwinddatabase.codeplex.com/

  5. iOS中的序列帧动画

    UIImageView对象的有一个animationImages属性,将图片数组赋值给该属性即可.如图: 控制动画的播放方法是:[ ___  startAnimating]; 控制动画的停止方法是:[ ...

  6. 12.equals()方法总结

    超类Object中有这个equals()方法,该方法主要用于比较两个对象是否相等.该方法的源码如下: 我们知道所有对象都有表示(内存地址)和状态(数据),看上面代码是用"=="来比 ...

  7. hdu 5092 线裁剪(纵向连线最小和+输出路径)

    http://acm.hdu.edu.cn/showproblem.php?pid=5092 给一个m*n的矩阵,找到一个纵向的"线"使得线上的和最小并输出这条线,线能向8个方向延 ...

  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 ...

  9. HTML超级链接详细讲解

    超级链接是网站中使用比较频繁的HTML元素,因为网站的各种页面都是由超级链接串接而成,超级链接完成了页面之间的跳转.超级链接是浏览者和服务器的交互的主要手段,在后面的技术中会逐步深化学习. —  注意 ...

  10. Markdown中怎么上传图片

    在网站中使用了Markdown编辑器,但是不能支持图片的直接粘贴