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. 2018.11.02 洛谷P2312 解方程(数论)

    传送门 直接做肯定会TLETLETLE. 于是考验乱搞能力的时候到了. 我们随便选几个质数来checkcheckcheck合法解,如果一个数无论怎么checkcheckcheck都是合法的那么就有很大 ...

  2. Codeforces Round #519 by Botan Investments F. Make It One

    https://codeforces.com/contest/1043/problem/F 题意 给你n个数,求一个最小集合,这个集合里面数的最大公因数等于1 1<=n<=3e5 1< ...

  3. PARSEC安环境配置、运行

    1.getting started 2.run PARSEC on simulators Full-System Simulators: such as Simics, GEM5.Trace-Driv ...

  4. Curator之Recipes之锁

    转载自:https://blog.csdn.net/kiss_the_sun/article/details/50221463 参考文档: http://ifeve.com/java_lock_see ...

  5. ubuntu16.04 编译安卓4.2

    1. root@ge-Lenovo:/usr/lib/jvm# cd /home/material/install/jdk/    jdk-6u29-linux-x64.bin  jdk-6u45-l ...

  6. centos7.2下安装python3.6.2

    centos7.2默认已经安装了python2.7.5,因此要安装python3.6的话,得从python官网上下载相应版本的安装包 查看python2.7 1.下载:wget https://www ...

  7. 记录:CSS选择器学习

    常用选择器:标签选择器.类选择器.ID选择器 子选择器(Child selectors) 还有一个比较有用的选择器子选择器,即大于符号(>),用于选择指定标签元素的第一代子元素. .con> ...

  8. (转)WCF中神秘的“8733"端口和“Design_Time_Addresses”

    转自:http://blog.csdn.net/bitfan/article/details/4193319 如果使用Visual Studio 2008 SP1开发WCF应用程序时,会发现当使用Vi ...

  9. 各种学习Demo链接

    CSS3: 钟表:http://demo.qpdiy.com/hxw/CSS3/css3_clock.html CSS3各种旋转:http://demo.qpdiy.com/hxw/CSS3/css3 ...

  10. Alpha冲刺 - (10/10)

    Part.1 开篇 队名:彳艮彳亍团队 组长博客:戳我进入 作业博客:班级博客本次作业的链接 Part.2 成员汇报 组员1(组长)柯奇豪 过去两天完成了哪些任务 本人负责的模块(共享编辑)的前端代码 ...