问题概述:
之前本系列博客写的,全部都是一个connection对象,不知道大家发现没有,我们既然做了一个Connection工具类,那么大家肯定都是从那里面拿Connection对象的,之前的如果是多线程运行,很容易出问题的,你想想事务处理就知道了,同时用事务处理操作同一个Connection,肯定会出问题的。
例如:
一方的事务在提交的时候,你正好运行了一个事务中的一个操作,那么你这个操作也会被提交,而且你后面的提交或回滚失效的,如果对方把Connection关闭了,你的程序还会挂。
等等问题…
那么,我们就需要一个Connection对象池,谁来了,就去池中拿对象,不会再是同一个了,而且可以很好的控制池中Connection对象的数目,不可能一直new Connection对象的,如果池中的对象用完了,我们就让那个客户端等,等别人用完Connection对象还回到池中。
配置文件:jdbc.propertise
ConnsUtil:Connection池
测试类:
在调用返回Connection对象回到池中的时候,用普通的调用,不可避免的要去调用自己写的一个返回方法,如何在不改变程序员变成习惯(一般都习惯用close()去关闭那个对象)的情况下去实现Connection对象的回收呢,那就需要用到装饰模式,或者代理模式了。
装饰模式:
装饰模式又名包装(Wrapper)模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任。换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展。
其实我们要做的就是写一个MyConnection类实现Connection接口,实现所有方法,再进行扩展!
测试类:
测试结果:
代理模式:
代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。
好处就是:
在某些情况下,如果不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
可以为原来的方法增加或者修改动作!
代理模式一般需要3个角色:
抽象角色:声明真实对象和代理对象的共同接口(必须是接口;
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装与包装。
真实角色(被代理的角色):代理角色所代表的真实对象,是我们最终要引用的对象。
代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。 代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后 续处理。
接口:
实际对象:
代理模式的核心部分:
可以看出来InvocationHandler这个接口中的invoke方法是最核心的部分!!!
在里面我们利用类加载器和类反射,直接可以来调用原来的类,而且可以加上自己需要的功能,或者实现拦截!!!
上面的例子只能实现对Renter 类的代理。
通用的代理模板类:
ProxyUtil.java
client
输出结果:
我们现在再来把之前用装饰模式写的ConnsUtil类改写成代理模式:
ConnsUtil类的代理模式:
大家可以自己动手写一写,加深印象, Proxy.newProxyInstance(类加载器,class数组(被代理对象的接口的class数组),new InvocationHandler());
记住这个就可以了!
被代理对象的接口的class数组可以用conn.getClass().getInterfaces(),来获得。
conn为被代理的对象!
动态代理比装饰模式方便很多!
---------------------
作者:谙忆
来源:CSDN
原文:https://blog.csdn.net/qq_26525215/article/details/52173862
版权声明:本文为博主原创文章,转载请附上博文链接!
网友评论