代理模式
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
按照代理的创建时期,代理类可以分为两种。
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建而成。
1.静态代理:
1.首先定义一个Subject接口
2.定义RealSubject和ProxySubject类实现Subject接口。
3.ProxySubject中要关联RealSubject,属性中包含一个RealSubject,使用构造方法初始化
4.先要创建一个RealSubject,然后再实例化一个ProxySubject代理类,使用代理类调用
静态代理模式
1.Subject 主体(抽象类或接口)
2.RealSubject 真实主题类
3.ProxySubject 代理主题类
要点:RealSubject和ProxySubject都需要实现Subject主题类,代理类要引用主题类
缺点:一个代理类只能为一个接口服务,如果实际类多了那么代理类也会非常的多。
Java对代理模式的支持:动态代理
2.动态代理:(是将来学习Spring基础)
1.首先定义一个Subject主题接口
2.定义一个代理主体类ProxyObject实现java 的 InvocationHandler接口
这样就把代理主题角色和我们的业务代码分离开来,使代理对象能通用于其他接口
3.其实InvocationHandler接口就是一种拦截机制,当系统中有了代理对象以后,对原对象(真实主题)方法的调用,都会转由InvocationHandler接口来处理,并把方法信息以参数的形式传递给invoke方法,这样,我们就可以在invoke方法中拦截原对象的调用,并通过反射机制来动态调用原对象的方法
动态代理设计模式:
1.Subject 主体接口
2.有许多个的主体接口的实现类 RealSubject1 、RealSubject2 、RealSubject3
3.有一个对象代理类ProxyObject
实现动态代理的租最主要的两个步骤:
对象代理类必须要实现java.lang.reflect.InvocationHandler接口。 是反射接口哦
java.lang.reflect.InvocationHandler接口
覆盖里面的invoke(Object proxy,Method method,Object[] args)方法
Public Object invoke(Object proxy,Mehtod method,Object[] args){
Befor do something;
Object result=method.invoke(target,args);
After do something;
Return result;
}
创建代理类实例对象的方法:
Proxy.newProxyInstance(loader,interfaces,h);
Proxy.newProxyInstance(subject1.getClass.getClassLoader(),subject1.getClass().getInterfaces(),proxy1)
有两种方式:
1.是在ProxyObject里面集成创建代理类实例对象方法
2.在客户端再边检创建代理实例类对象方法
动态代理代码模板:
Subject主题接口:自定的主题接口
RealSubject1真实主题1:实现某个主题接口
RealSubject2真实主题2:实现某个主题接口
ProxyObject代理主题: 只需要实现java反射包下的InvocationHandler接口,不需要实现任何Subject接口。
代理主体类的实现代码可参考:
package com.xuyi.dynic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyObject implements InvocationHandler {
private Object target;
public Object createProxy(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("执行之前 do something...");
Object result = method.invoke(target, args);
System.out.println("执行之后do something ...");
return result;
}
}