java之Spring(AOP)前奏-动态代理设计模式(下)
在上一章我们看到了,新增的三种类都能实现对原始功能类进行添加功能的事务处理,这三种类就是一个代理。
但是这种代理是写死的,怎样实现对任意接口添加自定义的代理呢?
我们先来看一下之前的代理实现:
public class Impeat {
private InterfaceDo todo;
public Impeat(InterfaceDo todo) {
super();
this.todo = todo;
}
public void dothings() {
todo.dosomething();
System.out.println("我要吃饭了啊--------");
}
}
因为这里我们的代理不需要再被其他代理引用,所以就不需要实现InterfaceDo接口,自然内部方法也是可以自定义,没有必要
遵循InterfaceDo的方法定义,为了避免混淆,我们将其改为了dothings(),由于代理类都是这样的一个书写模式:定义成员变量、
构造函数为成员变量赋值为代理对象、自定义方法实现对代理对象方法的调用。我们索性定义一个接口,以后所有的代理类都按
照统一模式来写,在JDK中就定义了这样的一个接口InvocationHandler,我们的代理类都实现这个接口,遵循它的书写方式,
下面我们再来看看代理类里面的元素:
InterfaceDo:需要代理对象的实现接口;
todo:需要代理的对象;
红字:为代理对象添加的功能实现;
todo.dosomething():代理对象的原始功能。
既然要实现动态代理,那么这个代理实现的部分源码,就不能写死了(被代理对象的接口、被代理的对象以及被代理对象内部的
方法),接口我们可以自定义,被代理对象我们可以new出来,但是被代理对象内部的方法是不确定的,A代理对象可能是A方法,
B代理对象可能是B方法,C代理对象可能是C方法。
所以,我们要动态获取代理对象的内部方法就得通过反射来获得。
被代理对象的方法怎么获得呢?由于被代理对象是实现了接口的,被代理对象的内部方法必定也是重写自接口的定义方法的。那么
我们就可以从接口入手,获取接口的方法定义。
来看看JDK的实现:
public class Handlerimp implements InvocationHandler {
private Object obj;
public Handlerimp(Object obj) {
super();
this.obj = obj;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("-----我要实现新的功能-----");
Object returnValue = method.invoke(obj, args);
return returnValue;
}
}
是不是很眼熟,对,这个和我们之前的静态代理实现模式一样。只不过底层已经用反射帮我们获得了被代理对象obj的方法method
以及方法的参数数组,然后通过被代理对象、方法、参数三者来执行被代理对象的方法-------method.invoke(proxy,args)。
接下来,我们实例化一个该代理类的实例:
public class Testperson {
public static void main(String[] args) {
InterfaceDo a = new Persontodo();
Handlerimp handler =new Handlerimp(a);
ClassLoader loader = a.getClass().getClassLoader();
Class[] interfaces = a.getClass().getInterfaces();
InterfaceDo subject = (InterfaceDo) Proxy.newProxyInstance(loader, interfaces, handler);
subject.dosomething();
subject.dothing();
}
}
我们可以看到,JDK中通过Proxy类的静态方法newProxyInstance()获得代理类实例;
该方法实现了对被代理对象所有方法的遍历,因此实现了对被代理对象所有方法的功能添加。
之后,我们就可以调用代理类的方法了。
java之Spring(AOP)前奏-动态代理设计模式(下)的更多相关文章
- Spring AOP 前奏--动态代理
- Spring AOP 和 动态代理技术
AOP 是什么东西 首先来说 AOP 并不是 Spring 框架的核心技术之一,AOP 全称 Aspect Orient Programming,即面向切面的编程.其要解决的问题就是在不改变源代码的情 ...
- Spring AOP --JDK动态代理方式
我们知道Spring是通过JDK或者CGLib实现动态代理的,今天我们讨论一下JDK实现动态代理的原理. 一.简述 Spring在解析Bean的定义之后会将Bean的定义生成一个BeanDefinit ...
- Spring AOP之动态代理
软件151 李飞瑶 一.Spring 动态代理中的基本概念 1.关注点(concern) 一个关注点可以是一个特定的问题,概念.或者应用程序的兴趣点.总而言之,应用程序必须达到一个目标 ...
- Spring AOP JDK动态代理与CGLib动态代理区别
静态代理与动态代理 静态代理 代理模式 (1)代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. (2)静态代理由 业务实现类.业务代理类 两部分 ...
- java之Spring(AOP)前奏-动态代理设计模式(上)
我们常常会遇到这样的事,项目经理让你为一个功能类再加一个功能A,然后你加班为这个类加上了功能A: 过了两天又来了新需求,再在A功能后面加上一个新功能B,你加班写好了这个功能B,加在了A后面:又过 了几 ...
- Java编程的逻辑 (86) - 动态代理
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...
- 浅谈Spring中JDK动态代理与CGLIB动态代理
前言Spring是Java程序员基本不可能绕开的一个框架,它的核心思想是IOC(控制反转)和AOP(面向切面编程).在Spring中这两个核心思想都是基于设计模式实现的,IOC思想的实现基于工厂模式, ...
- AOP jdk动态代理
一: jdk动态代理是Spring AOP默认的代理方法.要求 被代理类要实现接口,只有接口里的方法才能被代理,主要步骤是先创建接口,接口里创建要被代理的方法,然后定义一个实现类实现该接口,接着将被代 ...
随机推荐
- 【Unity Shaders】Reflecting Your World —— 在Unity3D中创建一个简单的动态Cubemap系统
本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...
- Dynamics CRM2013 业务规则的新建、激活与删除
CRM2013的一个新的feature叫做业务规则,一些页面的简单的显示隐藏的控制.字段是否必填.有条件的锁定字段.错误提示等等,以前都是需要些脚本代码实现现在只需通过业务规则做一些简单的配置就可以达 ...
- 单元测试junit框架详解
首先在给出一个类Operator,加入如下代码: public class Operator { // 加法 运算 public int add(int i,int j){ return i+j; } ...
- 常用Petri网模拟软件工具简介
常用Petri网模拟软件工具简介 首先要介绍的的一个非常有名的Petri 网网站--Petri Nets World: http://www.informatik.uni-hamburg. ...
- JSP编译成Servlet(四)JSP与Java行关系映射
我们知道java虚拟机只认识class文件,要在虚拟机上运行就必须要遵守class文件格式,所以JSP编译成servlet后还需要进一步编译成class文件,但从JSP文件到java文件再到class ...
- Java虚拟机结构
一.JVM主要的结构如下: 二.各个区域功能介绍 1).方法区(Method Area): (1)用于存储虚拟机加载的类信息.常量.静态变量等,是各个线程共享的内存区域: ...
- ISLR系列:(2)分类 Logistic Regression & LDA & QDA & KNN
Classification 此博文是 An Introduction to Statistical Learning with Applications in R 的系列读书笔记,作为本人的一 ...
- Android安全机制浅谈-android学习之旅(80)
由于Android安全机制存在,使得漏洞利用有一些困难. ASLR:即地址空间格局随机化.ASLR使得加载程序时不使用固定的基址加载,防止攻击者直接定位攻击代码位置,从而阻止溢出攻击 NX:(No e ...
- RHEL6安装python包tornado
RHEL6安装python包tornado tornado是使用Python开发的全栈式(full-stack)Web框架和异步网络库,最早由Friendfeed开发.通过使用非阻塞IO,Tornad ...
- 如何在代码中取得一个特点type的关节
我们可以在初始化方法中添加如下代码: -(void)didLoadFromCCB{ Class distanceJointClass = NSClassFromString(@"CCPhys ...