java之代理模式
静态代理:
java代理是一种模式--代理模式。采用代理模式,可以在不改变目标类代码的基础上,通过代理对象,来增加额外的功能(比如增加日志检测等)或者只需要目标对象的部分行为。
java中,代理分为静态代理和动态代理。
静态代理:我的理解是程序员自己或者用某些工具去自己创建或者生成代理类。在使用之前,代理类已经存在。
动态代理:区别于静态代理,它是动态的,不需要程序员去自己创建,只需要采用现成的动态代理类库(jdk动态代理,cglib)调用某些类的某些方法,动态生成代理类。代理类在使用之前是不存在的。什么时候使用,什么时候创建。是动态的。
静态代理:
静态代理有两种实现方式。
1.合成
即将目标类作为代理类的全局成员。需要目标类实现接口
接口:
package com.wtd.staticproxy;
public interface Moveable {
void move();
}
目标类:
package com.wtd.staticproxy; import java.util.Random; /**
* @desc Car:被代理对象,真实对象
* */
public class Car implements Moveable { @Override
public void move() {
try {
System.out.println("the car is running");
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
代理类:
package com.wtd.staticproxy; /**
* @desc 静态代理 第二种方式:合成。
* 静态代理,说白了,就是手动创建 代理类。手动创建的两种方式[继承,合成]
* */
public class Car2 implements Moveable {//代理类:必须和被代理类都实现统一的接口
Car car;//被代理类类 (真实类)
public Car2(Car car) {
super();
this.car= car;
}
@Override
public void move() {
System.out.println("the car start");//业余方法
long startTime= System.currentTimeMillis();//业余方法
car.move();//调用被代理类的功能方法
long endTime= System.currentTimeMillis();//业余方法
System.out.println("the car stop,use time:"+ (endTime-startTime)+"ms");//业余方法
} }
测试类:
package com.wtd.staticproxy;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
Car car = new Car();//创建被代理类(真实类)
Moveable m2= new Car2(car);//创建代理类
m2.move();
}
}
output:
the car start
the car is running
the car stop,use time:681ms
2.继承
代理类继承目标类。不需要目标类继承接口。但是目标类必须不能被final修饰
目标类:
package com.wtd.staticproxy; import java.util.Random; /**
* @desc Car:被代理对象,真实对象
* */
public class Car { public void move() {
try {
System.out.println("the car is running");
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
代理类:
package com.wtd.staticproxy; /**
* @desc 静态代理有两种方式, 这是第一种:继承的方式、
* 第二种:合成
* */
public class Car1 extends Car{
@Override
public void move() {
System.out.println("汽车开始行驶");//业余方法
long startTime= System.currentTimeMillis();//业余方法
super.move();//调用父类的功能方法
long endTime= System.currentTimeMillis();//业余方法
System.out.println("汽车行驶结束,行驶了:"+ (endTime- startTime)+"毫秒");//业余方法
}
}
测试类:
package com.wtd.staticproxy;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
Car m= new Car1();
m.move();
}
}
output:
the car start
the car is running
the car stop,use time:361ms
动态代理:
原理:类似于静态代理中的合成。被代理对象必须继承某一接口
接口:
package com.wtd.dynamicproxy3;
public interface Moveable {
void move();
void run(String args);
}
目标对象(被代理对象):
package com.wtd.dynamicproxy3;
public class Car implements Moveable {
@Override
public void move() {
System.out.println("Car move()");
}
@Override
public void run(String args) {
System.out.println("Car run()"+ args);
}
}
调用处理器对象:InvocationHandler对象
package com.wtd.dynamicproxy3; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; public class LogHandler implements InvocationHandler {
private Object proxied;
public LogHandler(Object proxied) {
this.proxied= proxied;
// TODO Auto-generated constructor stub
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println(
"----------proxy: "
+ proxy.getClass()
+ ", method: "
+ method+ ", args: "
+ args+ ", proxied: "
+ proxied.getClass()); return method.invoke(proxied, args);
} }
测试类:
package com.wtd.dynamicproxy3;
import java.lang.reflect.Proxy;
public class TestDynamicProxy {
public static void main(String[] args) {
Car car= new Car();
Moveable m= (Moveable) Proxy.newProxyInstance(Moveable.class.getClassLoader(),
new Class<?>[]{Moveable.class},
new LogHandler(car));
m.move();
m.run("haha");
}
}
output:
----------proxy: class com.sun.proxy.$Proxy0, method: public abstract void com.wtd.dynamicproxy3.Moveable.move(), args: null, proxied: class com.wtd.dynamicproxy3.Car
Car move()
----------proxy: class com.sun.proxy.$Proxy0, method: public abstract void com.wtd.dynamicproxy3.Moveable.run(java.lang.String), args: [Ljava.lang.Object;@5e743399, proxied: class com.wtd.dynamicproxy3.Car
Car run()haha
cglib动态代理:
原理:类似于静态代理中的继承方式。被代理对象的类不能被final所修饰
首先需要导入jar包:cglib-nodep-x.x.x.jar。可在mvnrepository下载。
被代理类:父类:realObject:
package com.wtd.cglibproxy; /**
* 目标类;父类;被代理类
* 不能被final所修饰
* */
public class Car {
public void move() {
System.out.println("the car running");
}
}
方法拦截器类:
package com.wtd.cglibproxy; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor {
private Enhancer enhancer = new Enhancer(); /**
* 设置获得代理对象(即子类对象)的方法
* 需要用到 Enhancer
* */
public Object getProxy(Class clazz){
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
} /**
* @author WesTward
* @param proxied:被代理对象,目标对象,父类对象
* @param method: 目标对象的 方法
* @param args: 目标对象的方法的参数
* @param proxy: 代理对象
* */
@Override
public Object intercept(Object proxied, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("Log---------start");
proxy.invokeSuper(proxied, args);
System.out.println("Log---------end");
return null;
} }
测试类:
package com.wtd.cglibproxy;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
CglibProxy cglibProxy= new CglibProxy();
Car car = (Car) cglibProxy.getProxy(Car.class);
car.move();
}
}
output:
Log---------start
the car running
Log---------end
附:
动态代理主要运用了java的反射机制。
java之代理模式的更多相关文章
- Java设计模式-代理模式之动态代理(附源代码分析)
Java设计模式-代理模式之动态代理(附源代码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的差别就是:动态代理是在执行时刻动态的创建出代理类及其对象. 上篇中的静态代 ...
- Java学习——代理模式
Java中的三种代理模式 一,什么是代理模式? 代理模式是一种设计模式,简单的来说就是在不改变源码的情况下,实现对目标对象的功能扩展. 比如有个歌手对象叫Singer,这个对象有一个唱歌方法叫sing ...
- JAVA动态代理模式(从现实生活角度理解代码原理)
所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. java动态代理主要是使用java.lang.reflect包中的两个 ...
- JAVA 设计模式 代理模式
用途 代理模式 (Proxy) 为其他对象提供一种代理以控制对这个对象的访问. 代理模式是一种结构型模式. 结构
- java 之 代理模式(大话设计模式)
java代理模式顾名思义,就类似于大学,我想和冰可乐,可是我又在玩游戏,于是我让我的室友帮我把可乐带回来,简单的来说我的室友就是代理,而买可乐就是需要做的行为.这是笔者理解的代理模式 大话设计模式-类 ...
- JAVA中代理模式
代理模式 在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为“代理”的第三者来实现间接引用.代理对象可以在客户端和目标对象之间起到 中介的作用,并且可以通过代理对象去掉客户不能 ...
- 【Java】代理模式、反射机制-动态代理
关于代理模式和动态代理参考自:https://www.cnblogs.com/gonjan-blog/p/6685611.html 这里通过参考博客中的例子整理个人理解. 代理模式: 访问某个类的方法 ...
- Java设计模式—代理模式
代理模式(Proxy Pattern)也叫做委托模式,是一个使用率非常高的模式. 定义如下: 为其他对象提供一种代理以控制对这个对象的访问. 个人理解: 代理模式将原类进行封装, ...
- Java设计模式の代理模式
目录 代理模式 1.1.静态代理 1.2.动态代理 1.3.Cglib代理 代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是 ...
随机推荐
- iOS - Swift Closure 闭包
1.Closure 闭包在 Swift 中非常有用.通俗的解释就是一个 Int 类型里存储着一个整数,一个 String 类型包含着一串字符,同样,闭包是一个包含着函数的类型.有了闭包,你就可以处理很 ...
- 理解odbc
1.解决什么样的问题?不同的数据库产品,具有不同的特性,也就是方言.因此应用程序针对不同的数据库产品,编写不同的代码.如果换了一个数据库产品,还需要重新编写数据库交互部分,不具备扩展和移植.odbc对 ...
- (二)stm32之中断配置
一.stm32的中断和异常 Cortex拥有强大的异常响应系统,它能够打断当前代码执行流程事件分为异常和中断,它们用一个表管理起来,编号为0~15为内核异常,16以上的为外部中断,这个表就是中断向量表 ...
- 【转载】高性能IO设计 & Java NIO & 同步/异步 阻塞/非阻塞 Reactor/Proactor
开始准备看Java NIO的,这篇文章:http://xly1981.iteye.com/blog/1735862 里面提到了这篇文章 http://xmuzyq.iteye.com/blog/783 ...
- CSS3学习笔记之属性值
font-family 设置文本的字体名称. font-style 设置文本样式. 取值 normal不使用斜体. italic使用斜体. oblique使用倾斜体. inherit从父元素继承. f ...
- 提高php开发效率的9大代码片段
在网站开发中,我们都期望能高效快速的进行程序开发,如果有能直接使用的代码片段,提高开发效率,那将是极好的.php开发福利来了,今天小编就将为大家分享9大超实用的.可节省大量开发时间的php代码片段. ...
- window下安装nodejs
下载nodejs 去https://nodejs.org/en/download/下载nodejs,有.mis(安装版)和.exe(二进制版) .mis(安装版) 一般下载这个就行,简单方便,自带np ...
- Edit Distance编辑距离(NM tag)- sam/bam格式解读进阶
sam格式很精炼,几乎包含了比对的所有信息,我们平常用到的信息很少,但特殊情况下,我们会用到一些较为生僻的信息,关于这些信息sam官方文档的介绍比较精简,直接看估计很难看懂. 今天要介绍的是如何通过b ...
- [转]Android_气泡效果
最近在看以前在eoe上收藏的一些源代码,准备将这些代码加上一些自己的注释,然后贴出来,方便自己日后查阅,和刚入门的人来学习. 今天先看一个气泡窗口,先看一下效果图和目录结构,然后再上代码 通过第一幅图 ...
- unity3d WorldComposer1 卫星地图生成地形
http://blog.csdn.net/myarrow/article/details/42709113 1. 简介 1.1 TerrainComposer(TC) 一个Unity扩展工具,可用于创 ...