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. 菜品识别 API调用

    #get_access_token.py #获取access_token 1 import requests def GetToken(API_KEY,SECRET_KEY): url = 'http ...

  2. latex去掉页眉

    \begin{document}之前添加 \fancyhead{} 即: \fancyhead{} \begin{document}

  3. python 基础_字符串9

    凡是重要的# 字符串的创建,字符串可以是单引号创建也可以是双引号创建 str1 = 'hello world' #当你要输出的是单引号的时候,你括起字符串的必须是双引号.当你输出的是双引号的时候,你括 ...

  4. Arria10中PHY的时钟线结构

    发送器时钟网络由发送器PLL到发送器通道,它为发送器提供两种时钟 高速串行时钟——串化器的高速时钟 低速并行时钟——串化器和PCS的低速时钟 在绑定通道模式,串行和并行时钟都是由发送器的PLL提供给发 ...

  5. Silverlight子窗口(ChildWindow)传递参数到父窗口演示

    在企业级项目中,子窗口(ChildWindow)是一个常用控件,其展示方式是以弹出窗口来显示信息. 这里我将演示,子窗口传递参数到父窗口的方法.由于我的开发环境都是英文环境,所以部分中文可能显示不正常 ...

  6. js基础学习笔记(三)

    3.1 认识DOM 文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法.DOM 将HTML文档呈现为带有元素.属性和文本的树结构(节点树). 先来看看 ...

  7. Android自定义视图四:定制onMeasure强制显示为方形

    这个系列是老外写的,干货!翻译出来一起学习.如有不妥,不吝赐教! Android自定义视图一:扩展现有的视图,添加新的XML属性 Android自定义视图二:如何绘制内容 Android自定义视图三: ...

  8. MapServer和GeoServer对比

    https://blog.csdn.net/theonegis/article/details/45823099

  9. 阿里云 oss实时日志查询

    实时日志查询 更新时间:2019-01-29 10:31:49 编辑 · 本页目录 开启实时日志查询 查询实时日志 参考文档 用户在访问 OSS 的过程中,会产生大量的访问日志.实时日志查询功能将 O ...

  10. java基本语法、标识符、关键字

    基本语法 编写Java程序时,应注意以下几点: 大小写敏感:Java是大小写敏感的,这就意味着标识符Hello与hello是不同的. 类名:对于所有的类来说,类名的首字母应该大写.如果类名由若干单词组 ...