代理模式
来源:互联网 发布:c语言void的用法 编辑:程序博客网 时间:2024/04/29 20:57
2 定义
为其他对象提供一种代理以控制对这个对象的访问。
代理类模板:
public class Proxy implements Subject { //要代理哪个实现类 private Subject subject = null; //默认被代理者 public Proxy(){ this.subject = new Proxy(); } //通过构造函数传递代理者 public Proxy(Object... objects) { } //实现接口中定义的方法 public void request() { this.before(); this.subject.request(); this.after(); } //预处理 private void before(){ //do something } //善后处理 private void after(){ //do something }}
3 运用
1) 优点
2) 使用场景
Spring AOP就是动态代理典型的例子。
4 扩展
1) 普通代理
要知道代理的存在,才能访问
2) 强制代理
直接调用真实角色,其代理的产生是有真实角色决定的。
3) 代理是有个性的
意思就是说会做一些代理自己想做的事。
4) 动态代理
动态代理是在实现阶段不同关心代理谁,而在运行阶段才指定代理哪一个对象。
动态代理的主要意图就是解决我们常说的“审计”问题,也就是横切面编程,在不改变我们已有代码结构的情况下增强或控制对象的行为。日志、事务、权限。
动态代理实现代理的职责,业务逻辑Subject实现相关的逻辑功能,两者之间没有必然的互相耦合的关系。
静态代理和动态代理的区别
package dongtaidaili;//抽象主题public interface Subject { //业务操作 public void doSomething(String str);}
package dongtaidaili;//真实主题public class RealSubject implements Subject { @Override public void doSomething(String str) { System.out.println("do somethingd----------->" + str); }}
package dongtaidaili;//通知接口public interface IAdvice { //通知只有一个方法,执行即可 public void exec();}
package dongtaidaili;public class BeforeAdvice implements IAdvice { @Override public void exec() { System.out.println("我是前置通知,我被执行了"); }}
package dongtaidaili;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;//动态代理的Handler类public class MyInvocationHandler implements InvocationHandler { //被代理的对象 private Object target; //通过构造函数传递一个对象 public MyInvocationHandler(Object object) { this.target = object; } //代理方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(this.target, args); }}
package dongtaidaili;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;//动态代理类public class DynamicProxy<T> { public static <T> T newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h){ //寻找连接点,AOP框架使用元数据定义 if(true) { //执行一个前置通知 (new BeforeAdvice()).exec(); } //执行目标,并返回结果 //h的实现类实现interfaces的所有方法,由其invoke方法接管所有方法的实现 return (T)Proxy.newProxyInstance(loader, interfaces, h); }}
package dongtaidaili;import java.lang.reflect.InvocationHandler;public class Client { public static void main(String[] args) { //定义一个主题 Subject subject = new RealSubject(); //定义一个Handler InvocationHandler handler = new MyInvocationHandler(subject); //定义主题的代理 Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), handler); //代理的行为 proxy.doSomething("Finish"); }}
package dongtaidaili;import java.lang.reflect.InvocationHandler;public class SubjectDynamicProxy extends DynamicProxy { public static <T> T newProxyInstance(Subject subject) { //获得ClassLoader ClassLoader loader = subject.getClass().getClassLoader(); //获得接口数组 Class<?>[] classes = subject.getClass().getInterfaces(); //获得handler InvocationHandler handler = new MyInvocationHandler(subject); return newProxyInstance(loader, classes, handler); }}
package dongtaidaili;public class Client2 { public static void main(String[] args) { Subject subject = new RealSubject(); Subject proxy = SubjectDynamicProxy.newProxyInstance(subject); proxy.doSomething("Finish!"); }}
添加一个要代理的接口:
package dongtaidaili;public interface Subject2 { public void doElseSomething(String str);}
package dongtaidaili;public class RealSubject2 implements Subject2 { @Override public void doElseSomething(String str) { System.out.println("do else something!" + str); }}
代理类完成不用修改:
package dongtaidaili;import java.lang.reflect.InvocationHandler;public class Client { public static void main(String[] args) { //定义一个主题 Subject subject = new RealSubject(); //定义一个Handler InvocationHandler handler = new MyInvocationHandler(subject); //定义主题的代理 Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), handler); //代理的行为 proxy.doSomething("Finish"); System.out.println("----------------动态代理比静态代理的优点----------------------"); Subject2 subject2 = new RealSubject2(); InvocationHandler handler2 = new MyInvocationHandler(subject2); Subject2 proxy2 = SubjectDynamicProxy.newProxyInstance(subject2.getClass().getClassLoader(), subject2.getClass().getInterfaces(),handler2); proxy2.doElseSomething("else Finish"); }}
5)静态代理
两个接口要写两个代理类
package dongtaidaili;public class SubjectProxy implements Subject { private Subject subject; public SubjectProxy(Subject subject) { super(); this.subject = subject; } @Override public void doSomething(String str) { System.out.println("前置通知,我被执行了"); this.subject.doSomething(str); }}
package dongtaidaili;public class Subject2Proxy implements Subject2 { private Subject2 subject2; public Subject2Proxy(Subject2 subject2) { super(); this.subject2 = subject2; } @Override public void doElseSomething(String str) { System.out.println("前置通知,我被执行了"); this.subject2.doElseSomething(str); }}
package dongtaidaili;public class SubjectProxyClient { public static void main(String[] args) { Subject subject = new RealSubject(); Subject proxy = new SubjectProxy(subject); proxy.doSomething("Finish"); System.out.println("-------静态代理的缺点,一个代理只服务于一个接口,会造成冗余代码------------"); Subject2 subjec2 = new RealSubject2(); Subject2 proxy2 = new Subject2Proxy(subjec2); proxy2.doElseSomething("else Finish"); }}
或者这样:
package dongtaidaili;public class Subject1_2Proxy implements Subject, Subject2 { private Subject subject; private Subject2 subject2; public Subject1_2Proxy(Subject subject, Subject2 subject2) { super(); this.subject = subject; this.subject2 = subject2; } @Override public void doElseSomething(String str) { System.out.println("前置通知,我被执行了"); this.subject2.doElseSomething(str); } @Override public void doSomething(String str) { System.out.println("前置通知,我被执行了"); this.subject.doSomething(str); }}
package dongtaidaili;public class SubjectProxyClient { public static void main(String[] args) { Subject subject = new RealSubject(); Subject proxy = new SubjectProxy(subject); proxy.doSomething("Finish"); System.out.println("-------静态代理的缺点,一个代理只服务于一个接口,会造成冗余代码------------"); Subject2 subjec2 = new RealSubject2(); Subject2 proxy2 = new Subject2Proxy(subjec2); proxy2.doElseSomething("else Finish"); System.out.println("-------------------------"); Subject proxy_1 = new Subject1_2Proxy(subject, null); proxy_1.doSomething("Hello world"); Subject2 proxy_2 = new Subject1_2Proxy(null, subjec2); proxy_2.doElseSomething("else Hello world"); }}
6)静态代理和动态代理优缺点
*代理的共同优点:
业务类只需要关注业务逻辑本身。
*静态代理缺点:
代理对象的一个接口只服务于一种类型的对象,如果代理的方法很多,要为每一个方法都进行代理。
* 动态代理的缺点
只有实现了某个接口的类才可以使用Java动态代理机制。但是有cglib(Code生成类库),可以在运行期扩展Java类与实现Java接口。
5 最佳实现
AOP
0 0
- 代理模式--动态代理
- 代理模式-静态代理
- 代理模式-静态代理
- 代理模式 & 动态代理
- 代理模式--静态代理
- 代理模式--动态代理
- 代理模式(动态代理)
- 代理模式-动态代理
- 代理模式-动态代理
- 代理模式动态代理
- 代理模式-静态代理
- 代理模式-动态代理
- 代理模式 -动态代理
- 代理模式---动态代理
- 代理模式-动态代理
- 代理模式--静态代理
- 代理模式!
- 代理模式
- 关于开发中的AppbarLayout问题
- Android播放Gif动态图片的几种方式
- 数字视音频处理知识点小结
- Code blocks
- Ruby中的类与对象(一)
- 代理模式
- 如何遍历某一文件夹下所有图片并切割制作负样本
- centos关机与重启命令详解
- python-c crash
- 【caffe源码研究】第三章:源码篇(10) :ConvolutionLayer
- windows下安装多个mysql5.7.16免安装版版本数据库
- 【LeetCode】 451. Sort Characters By Frequency
- Hello word!
- Linux yum命令详解