今天介绍一下代理设计模式,在业务场景中使用代理模式的好处有很多,包括什么权限校验,事务管理等等,具体有什么好处大家自动百度吧,我这里只解释代理模式的设计原理。首先这个设计模式出来的时候先是静态代理模式,只有理解了静态代理模式,才能理解JDK提供的动态代理是怎么回事,首先介绍静态代理,如果有错误的地方请大家不要拍砖,请大家指正。  

    一,静态代理 

    第一种情况:假如我去租房,没有经过中介,直接找到了房屋的主人。这里抽象一下就是我直接访问了真实对象(房屋的主人),然后我把房屋给租了。

    第二种情况:假如我去租房,需要经过中介,找到一家租房的中介公司,然后把房屋租了。这里抽象一下就是我访问了真实对象的代理对象(中介),这里的代理对象(中介)需要持有真实对象(房屋主人)才能把房屋租给我(因为中介手里没有房子,他肯定要有房屋真实主人的房子才行)。结构图如下:

                

    大家一定要明白的是,代理对象(中介)一定要持有真实对象(房屋主人)才行。

    下边是静态代理的代码实现:

    首先代理对象和真实对象都需要实现同一个接口或继承抽象类,这个接口或者抽象类其实就是说我这里是租房屋的,不是租汽车的或别的东西,接口中定义一个quote(报价)方法。   

public interface Subject {
/***
* 这个接口定义一个报价方法
*/
public String quote(); }

    然后定义一个真实对象类,就是代表真实的房屋的主人,实现Subject接口,同时实现报价方法:

public class RealSubject implements Subject {
@Override
public String quote() {
return "房屋出租2000元一个月";
}
}

    定义一个代理类,这个代理类一定持有真实对象的引用

public class ProxySubject implements Subject{
@Override
public String quote() {
//代理对象持有真实对象
Subject subject = new RealSubject();
//返回真实对象的报价多少钱
String quote = subject.quote();
//代理对象增加真实对象的报价
return quote.replace("2000", "3000");
}
}

  编写我们的测试类,租房去找中介,然后查看房屋的报价是多少钱

public static void main(String[] args) {
/**
* 代理对象和真实对象都要实现同一个接口
*/
//直接访问真实对象
Subject subject = new RealSubject();
System.out.println(subject.quote()); //访问代理对象
subject = new ProxySubject();
System.out.println(subject.quote());
}

    执行之后会发现中介把房屋的租金增加了,这就起到了代理的作用。这就是一个静态代理的小例子,静态代理主要注意两点:1,真实类和代理类都实现一个相同的接口;2,代理类持有真实类的对象的引用。按照租房的情况说明就是:中介和房租主人都必须是卖房子的,不能你去中介租房,结果给你返回一个汽车的报价;中介必须有房屋主人的房子才能租给你,如果中介手中没有房子,只是一个空壳子,也没有办法把房子租给你。

    静态代理的一个不好的地方是如果接口里增加了一个方法,那么真实类和代理类都必须实现相应的方法,增加了代码的复杂程度。还有就是如果代理类没有实现接口怎么办(解决办法自行百度吧 ^_^)

    二,动态代理

    JDK提供了一个java.lang.reflect.Proxy对象,可以用来对真实类实现动态代理,在运行时通过反射增强真实类。我们这里给Subject接口增加一个方法  getHouseAddress(得到房子的地址),然后真实类实现这个方法,返回"房屋的地址在地球";代码如下:

    

public class RealSubjectHome implements Subject{

    @Override
public String quote() {
return "房屋出租2000元";
} @Override
public String getHouseAddress() {
return "房屋的地址在地球";
}
}

     这里我们看一下代理类的实现(主要的解释都在注释中):

public final class DynamicProxy implements InvocationHandler{

    //代理对象是要持有真实对象
private Object RealObject; public Object createSubject(Object RealObject){
/**
* 参数含义:
* classloader 是代理的类加载器
* interface 就是代理类实现的接口,因为代理类需要和真实对象实现相同的接口,所以返回的就是真实类的接口
* InvocationHandler 调用真实类的处理函数,代理类需要对真实对象做一些处理
* 返回值 返回一个真实类的代理对象
*
*/
this.RealObject = RealObject;
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
this.RealObject.getClass().getInterfaces(), //这里是真实对象实现的接口,代理对象也要实现相同的接口
this);
}
/**
* 参数:
* proxy 就是代理类的对象
* method 就是需要调用的实现接口中的方法
* args 方法中的参数
* 返回值 返回代理类调用实现接口的方法的返回值
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//调用真实对象中的方法,获取返回值
if(method.getName().equals("quote")){
String returnValue = (String) method.invoke(this.RealObject, args);
returnValue = returnValue.replace("2000", "3000");
return returnValue;
}
//其他不需要代理类修改的方法
return method.invoke(this.RealObject, args);
}
}

      其中Proxy.newProxyInstance方法返回一个代理对象,其中的第三个参数是实现InvocationHandler的接口,当调用代理对象的方法的时候,会调用InvocationHandler接口中的invoke方法用来对真实对象的方法增强,我们在invoke方法中只修改了获得房屋报价的内容。对获得房屋地址方法没有进行更改,直接调用真实对象的方法就行了。解释一下就是中介会把房屋的出租价格提高,但是房屋的地址不能修改吧,所以动态代理可以很好的控制需要增强的方法。

      看一下我们的测试类:

public static void main(String[] args) {

        //找代理出租房屋
RealSubjectHome subjecthome = new RealSubjectHome();
DynamicProxy proxy = new DynamicProxy();
Subject subject = (Subject) proxy.createSubject(subjecthome);
//得到房屋的报价信息
System.out.println(subject.quote());
//得到房屋的地址
System.out.println(subject.getHouseAddress());
}

    使用动态代理编写代理类的时候,其实并不难,只要注意两点就行了:1,代理类持有真实类的引用 2,代理类和真实类实现同一个接口。然后要多proxy类的newProxyInstance的参数含义理解,对InvocationHandler中的invoke方法的参数理解,就可以了。

    动态代理的思想在框架中使用的很多,其实使用jdk提供的动态代理的实现并不是很多,都是使用三方的实现,例如CGLIB,直接对类的字节码文件进行增强。静态代理和动态代理的实现就先这样,如果叙述中有错误,请指明。

Java静态代理和动态代理的更多相关文章

  1. 【Java】代处理?代理模式 - 静态代理,动态代理

    >不用代理 有时候,我希望在一些方法前后都打印一些日志,于是有了如下代码. 这是一个处理float类型加法的方法,我想在调用它前打印一下参数,调用后打印下计算结果.(至于为什么不直接用+号运算, ...

  2. Java:静态代理 and 动态代理

    代理模式是常用的设计模式,其特征是代理类与委托类具有相同的接口,在具体实现上,有静态代理和动态代理之分.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并 ...

  3. Java基础-静态代理与动态代理比较

    JAVA的静态代理与动态代理比较 静态代理类: 由程序员创建或由特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就已经存在了.动态代理类: 在程序运行时,运用反射机制动态创建 ...

  4. java中静态代理,动态代理知识的补充

    文章转载自:http://blog.csdn.net/jialinqiang/article/details/8950989 一.Java动态代理 相对于静态代理的代理类在编译时生成(.class文件 ...

  5. java静态代理与动态代理简单分析

    原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/5860749.html 1.动态代理(Dynamic Proxy) 代理分为静态代理和动态代理 ...

  6. 黑马程序员:Java基础总结----静态代理模式&动态代理

    黑马程序员:Java基础总结 静态代理模式&动态代理   ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 静态代理模式 public  class  Ts {   ...

  7. java中的静态代理和动态代理,入门整理

    静态代理和动态代理主要解决的问题是:在直接访问对象时带来的问题,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后 ...

  8. Java 静态代理与动态代理

    代理模式 设想你的项目依赖第三方,但是你需要对其接口做一些数据检验.性能数据记录.异常处理等,合适的方法就是使用设计模式里的代理模式. 代理模式是常用的java设计模式,代理类与委托类有同样的接口,代 ...

  9. java之静态代理和动态代理

    我们以几个问题,来开始我们今天的学习,如果下面几个问题,你都能说出个一二,那么恭喜你,你已经掌握了这方面的知识.1,什么是代理模式?2,Java中,静态代理与动态代理的区别?3,Spring使用的是J ...

随机推荐

  1. SQL2005性能分析一些细节功能你是否有用到?(三)

    原文:SQL2005性能分析一些细节功能你是否有用到?(三) 继上篇: SQL2005性能分析一些细节功能你是否有用到?(二) 第一: SET STATISTICS PROFILE ON 当我们比较查 ...

  2. iOS开发---转换坐标系

    - (void)viewDidLoad { [super viewDidLoad]; // 蓝色 UIView *blue = [[UIView alloc] init]; blue.backgrou ...

  3. The Swift Programming Language-官方教程精译Swift(8)闭包 -- Closures

    闭包是功能性自包含模块,可以在代码中被传递和使用. Swift 中的闭包与 C 和 Objective-C中的 blocks 以及其他一些编程语言中的 lambdas 比较相似. 闭包可以捕获和存储其 ...

  4. Object-C 基础学习笔记(for,foreach,while,switch)

    int main(int argc, const char * argv[]) { //for,foreach,while,do-while,switch NSMutableArray* mutabl ...

  5. 布尔逻辑运算,goto语句

    布尔逻辑 bool类型可以有两个值:true或者false. 布尔比较需要使用布尔比较运算符(关系运算符),下图:var1为布尔类型的变量,var2,var3则可以是不同类型.

  6. Oracle数据库面试题

    1.取出表中第31到40行的记录 mysql方案:select * from t order by id limit 30,10 oracle方案: select t2.* from (select ...

  7. ASP.NET MVC IOC 之Ninject攻略

    ASP.NET MVC IOC 之Ninject攻略 一.为什么要使用Ninject? 很多其它类型的IOC容器过于依赖配置文件,老是配置,总感觉有点不爽,而且要使用assembly-qualifie ...

  8. 在Idea中调试ant应用

    Ant调试 Ant调试 ant 是一种非常方便的打包,部署的工具,通过ant,可以一键构建整个项目,虽然MVN也支持这种功能,但是MVN混杂了package管理的功能,并且不是很自由,学习成本比较高. ...

  9. POCO Controller

    ---恢复内容开始--- POCO Controller 你这么厉害,ASP.NET vNext 知道吗?   写在前面 阅读目录: POCO 是什么? 为什么会有 POJO? POJO 的意义 PO ...

  10. 如何在网页启动Windows服务

    由于公司有许多windows服务进行业务的处理,所以对服务的维护也是一个比较头痛的问题,因为自己也不知道服务什么时候自动停了,而且更主要的原因是服务都是由运维部门在维护管理,开发这边没有直接操作服务的 ...