代理模式(Proxy):为其他对象提供一种代理以控制这个对象的访问。
代理模式类别:
1.远程代理:为一个对象在不同的地址空间提供局部代理,这样可以隐藏一个对象存在于不同地址空间的事实。比如:使用nexus构建私服就相当于是使用远程代
理的方式,使得工程依赖的jar包不要一直去远程访问。
2.虚拟代理:根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。这样就可以在一定的程度上提升系统的性能。
3.安全代理:用来控制真实对象访问时的权限。一般用于对象应该有不同的访问权限的时候。
4.智能指引:是指当调用真实对象时,代理处理另外的一些事情。如:计算真实对象的引用次数,这样当该对象没有引用是,可以自动释放它;或当第一次引用一
个持久对象时,将它装入内存;或在访问一个实际对象前,检查是否已经锁定它,以确保其他对象不能改变它,这些都是通过代理在访问一个对象时附加一些内部的处
理。
总之,代理模式其实就是在访问对象时插入一定程度的间接性处理,因为这种机制可以附加多种用途。
上面讲解都是理论上的东西,下面结合代码来分析一下代理模式中的两种代理模式:静态代理和动态代理
代理模式一般涉及到三个角色:
1.抽象角色:声明真实角色的接口
2.真实角色:抽象角色的实现
3.代理角色:代理角色内可以含有真实角色的引用,同时可以实现一些附加操作
一、静态代理
静态代理:静态代理中就是简单的将真实角色中的方法重新实现,重载抽象类中声明的方法。
静态代理的缺点是代理与真实角色一一对应,所以对于每一个要被代理的类,都要有一个代理类与之对应,并且都要实现抽象角色中的所有方法。所以这样代码的
复用率就下降了。
下面就贴出代码:
A.抽象角色:
package com.jjyy.jdbc.inter;
/**
* 电话的接口
*
* @author JiangYu 2015年3月29日
*
*/
public interface Phone {
/**
* call 方法
*/
public void call();
/**
* sendMsg 方法
*/
public void sendMsg();
}
B.代理角色
package com.jjyy.jdbc.decoration;
import com.jjyy.jdbc.inter.Phone;
/**
* 静态代理模式---前提是对象已经存在了
* @author JiangYu
* 2015年3月29日
*
*/
public class DecorateSamsungPhone implements Phone{
private Phone phone = null;
//通过构造方法传递对象
public DecorateSamsungPhone(Phone phone) {
this.phone = phone;
}
@Override
public void call() {
phone.call();
}
@Override
public void sendMsg() {
System.out.println("SamsungPhone sendMsg:Hello Samsung");
}
}
C.真实对象
package com.jjyy.jdbc.decoration;
import com.jjyy.jdbc.inter.Phone;
/**
* 静态代理设计模式
* 真实类要和代理类要实现相同的接口
* 在代理类的构造方法中传入被代理类的对象,这样就可以使用被代理对象的方法进行不同的装饰
* @author JiangYu
* 2015年3月29日
*
*/
public class SamsungPhone implements Phone {
@Override
public void call() {
System.out.println("SumsungPhone call...");
}
@Override
public void sendMsg() {
System.out.println("Phone sendMsg...");
}
}
D.测试类:
package com.jjyy.jdbc.decoration;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.junit.Test;
import com.jjyy.jdbc.dynamicProxy.DynamicProxyIPhone;
import com.jjyy.jdbc.inter.Phone;
/**
* 静态代理模式和动态代理设计模式
* @author JiangYu
* 2015年3月29日
*
*/
public class DesignModel {
/**
* 静态代理设计模式
*/
@Test
public void decorationDesignTest(){
//被装饰类
SamsungPhone phone = new SamsungPhone();
//装饰类
DecorateSamsungPhone samsungPhone = new DecorateSamsungPhone(phone);
//调用装饰之后的对象的方法
samsungPhone.call();
samsungPhone.sendMsg();
}
}
二、动态代理
动态代理:为了解决静态代理的问题----代码的复用率低。动态代理一般要满足代理的三个角色,然后还要实现一个接口---InvocationHandler,该接口中有一
个invoke方法。
理论的知识有点抽象,贴出代码:
A.真实角色
package com.jjyy.jdbc.decoration;
import com.jjyy.jdbc.inter.Phone;
/**
* 动态代理:真实角色
* @author JiangYu
* 2015年3月29日
*
*/
public class IPhone implements Phone{
@Override
public void call() {
System.out.println("IPhone call...");
}
@Override
public void sendMsg() {
System.out.println("IPhone sendMsg...");
}
}
B.代理角色
package com.jjyy.jdbc.dynamicProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 动态代理类--代理类
* @author JiangYu
* 2015年3月29日
*
*/
public class DynamicProxyIPhone implements InvocationHandler {
private Object obj = null;
public Object registerObj(Object obj){
this.obj = obj;
//所有的接口都绑定到了代理类对象上,保证真实对象和代理对象有着共同的行为
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("dynamic Proxy...");
//代理对象处理特殊的方法
if ("sendMsg".endsWith(method.getName())) {
System.out.println("IPhone sendMsg:Hello IPhone From DynamicProxy...");
return null;
}else {
return method.invoke(this.obj, args);
}
}
}
C.测试类
package com.jjyy.jdbc.decoration;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.junit.Test;
import com.jjyy.jdbc.dynamicProxy.DynamicProxyIPhone;
import com.jjyy.jdbc.inter.Phone;
/**
* 静态代理模式和动态代理设计模式
* @author JiangYu
* 2015年3月29日
*
*/
public class DesignModel {
/**
* 动态代理设计模式--实现方式之二
* 1.真实类和代理类具有相同的行为
* 2.代理类要实现InvocationHandler接口,事项invoke方法
* 3.代理类可以对真实类的行为进行增强
* 4.调用代理类对象的方法
*/
@Test
public void dynamicProxyDesignTest(){
//真实类
IPhone phone = new IPhone();
//代理类
DynamicProxyIPhone proxy = new DynamicProxyIPhone();
//代理对象
IPhone proxyPhone = (IPhone) proxy.registerObj(phone);
//调用代理对象的方法
proxyPhone.call();
proxyPhone.sendMsg();
}
}
上面的动态代理方式是一种常规的方式,另外还有一种方式是比较常用的动态代理写法--在测试类中直接用内部类来实现InvocationHandler
package com.jjyy.jdbc.decoration;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.junit.Test;
import com.jjyy.jdbc.dynamicProxy.DynamicProxyIPhone;
import com.jjyy.jdbc.inter.Phone;
/**
* 静态代理模式和动态代理设计模式
* @author JiangYu
* 2015年3月29日
*
*/
public class DesignModel {
/**
* 动态代理设计模式--实现方式之一
*/
@Test
public void proxyDesignTest(){
final IPhone iPhone = new IPhone();
//动态代理
Phone proxy = (Phone) Proxy.newProxyInstance(IPhone.class.getClassLoader(), IPhone.class.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if("sendMsg".equals(method.getName())){//如果是sendMsg时,就进行特殊的处理
System.out.println("Iphone sendMsg:Hello IPhone");
return null;
}else {//其他的方法还是按照原来的方法进行
return method.invoke(iPhone, args);
}
}
});
//通过代理对象去执行响应的方法
proxy.call();
proxy.sendMsg();
}
}
以上的动态代理是jdk的proxy,其实它也不是完美的,它只能代理实现了接口的类,不能对类本身实现代理,如果要完成对类本身实现代理,需要用到一个开源的
cglib。
分享到:
相关推荐
java.proxy,代理模式源码,设计模式,apache开源项目源码commons-proxy-1.0-src 各种代理模式操作的工具类源码以及代理模式案例源码,你会从中得到意想不到的效果! apache开源组织开发的开源项目源码,其优良的代码...
设计模式C++学习之代理模式(Proxy)
1.1 什么是设计模式 2 1.2 Smalltalk MVC 中的设计模式 3 1.3 描述设计模式 4 1.4 设计模式的编目 5 1.5 组织编目 7 1.6 设计模式怎样解决设计问题 8 1.6.1 寻找合适的对象 8 1.6.2 决定对象的粒度 9 1.6.3 指定对象...
JAVA设计模式-day2,请的行业大能讲得课程,涉及:创建模式(5种: 1、 工厂方法模式(Factory Method); 2、 抽象工厂模式; 3、 单例模式(Singleton) • 4、 建造者模式(Builder); 5、 原型模式(Prototype...
Java设计模式精讲-代理模式
《asp.net设计模式》涵盖了开发企业级asp.net应用程序的知名模式和最佳实践。本书用到的模式可以用于从asp.net1.0到asp.net 4.0的任何版本。不必管模式本身所用的语言,可以将模式用于任何面向对象编程语言。 ...
Android设计模式之代理模式(Proxy Pattern)
4.7 PROXY(代理)——对象结构型模式 4.8 结构型模式的讨论 第五章 行为模式 5.1 CHAIN OF RESPONSIBIL ITY(职责链)——对象行为型模式 5.2 COMMAND(命令)——对象行为型模式 5.3 INTERPRETER(解释器)——类...
第11章 代理模式(Proxy) 第12章 观察者模式(Observer) 第13章 命令模式(Command) 第14章 迭代器模式(Iterator) 第15章 组合模式(Composite) 第16章 模板方法模式(Template Method) 第17章 策略模式...
为其他对象提供一个代理以控制对这个对象的访问。
第11章 代理模式(Proxy) 第12章 观察者模式(Observer) 第13章 命令模式(Command) 第14章 迭代器模式(Iterator) 第15章 组合模式(Composite) 第16章 模板方法模式(Template Method) 第17章 策略模式...
第11章 代理模式(Proxy) 第12章 观察者模式(Observer) 第13章 命令模式(Command) 第14章 迭代器模式(Iterator) 第15章 组合模式(Composite) 第16章 模板方法模式(Template Method) 第17章 策略模式...
代码仅供参考学习 。
C#面向对象设计模式纵横谈(13):Proxy 代理模式(结构型模式)
详解设计模式中的proxy代理模式及在Java程序中的实现共14页.pdf.zip
C#面向对象设计模式纵横谈(13):Proxy 代理模式(结构型模式) (Level 300)
- 23种设计模式 - 工厂方法模式(Factory Method) - 抽象工厂模式(Abstract Factory) - 单例模式(Singleton) - 建造者模式(Builder) - 原型模式(Prototype) - 代理模式(Proxy) - 适配器模式(Adapter) - 装饰...
NULL 博文链接:https://wy649898543.iteye.com/blog/1431997
C++设计模式课件15_Proxy_代理模式.pdf
设计模式之Proxy(代理) 设计模式之Adapter(适配器) 设计模式之Composite(组合) 设计模式之Decorator(油漆工) 设计模式之Bridge 设计模式之Flyweight(享元) 行为模式: 设计模式之Template 设计模式之Memento(备忘机制...