代理模式分为2种
其实就是实现一个代理类,来代理你所需要代理的类,访问的时候,通过访问代理类,来达到一定的效果
举个例子:
权限:有一个系统有很多权限,比如说只有管理员有增加的功能.用户访问到DAO的saveMessage方法
这个其实就是真正需要的保存方法,但是只有管理员才有权限
public class DbMessage implements Message{
...
public void saveMessage(String name) throws ForumAlreadyExistsException {
this.name = name;
//这里真正将新名称保存到数据库中
saveToDb();
}
}
怎么办了,创建一个代理类
public class MessageProxy implements Message{
private DbMessage dbMessage;
private UserBean user;
public ForumProxy(DbMessage dbMessage, UserBean user)
{
this.dbMessage= dbMessage;
this.user= user;
}
.....
public void saveMessage(String name) throws Exception
{
//只有是系统或论坛管理者才可以修改名称
if (user.getRight.equal("***")) {
forum.saveMessage(name);
}
else {
throw new Exception();
}
}
}
利用代理类来实现权限的判断,Jive论坛系统的权限好象采用的代理模式,不过如果不是很了解的人,用起来可能会为了使用
代理模式而写代理模式,这样就违背了原来的意愿,只有写了一定多的代码的人才能炉火纯青的写.我只能表面理解.
1:静态代理.静态代理代理和被代理对象在代理之前是确定的。他们都实现相同的接口或者继承相同的抽象类。
上面的权限采用的也是静态代理
贴一些网上面比较有说明性的代码
Subject.java
/**
* 抽象角色
*/
public abstract class Subject {
abstract public void request();
}
RealSubject.java
/**
* 真实角色:实现了Subject的request()方法
*/
public class RealSubject extends Subject {
public RealSubject() {
}
public void request() {
System.out.println("真实角色的请求方法RealSubject.request()被调用!");
}
}
ProxySubject.java
/**
* 代理角色
*/
public class ProxySubject extends Subject {
private RealSubject realSubject; // 以真实角色作为代理角色的属性
public ProxySubject() {
}
// 该方法封装了真实对象的request方法
public void request() {
preRequest(); //代理前执行的操作
if (realSubject == null) {
realSubject = new RealSubject();
}
realSubject.request(); // 此处执行真实对象的request方法
postRequest(); //代理后执行的操作
}
private void preRequest() {
// something you want to do before requesting
System.out.println("代理前执行的操作ProxySubject.preRequest()!");
}
private void postRequest() {
// something you want to do after requesting
System.out.println("代理后执行的操作ProxySubject.postRequest()!");
}
}
Client.java
/**
* 客户端调用
*/
public class Client {
public static void main(String[] args) {
Subject sub = new ProxySubject();
sub.request();
}
}
这就是静态代理,通过访问代理类,来实现想要的方法,
客户实际需要调用的是RealSubject类的request()方法,现在用ProxySubject来代理 RealSubject类,同样达
到目的,同时还封装了其他方法(preRequest(),postRequest()),可以处理一些其他问题。
2:动态代理
如果事先并不知道真实角色,该如何使用代理,这就是动态代理所要解决的问题.
以下引用
底下的例子和上面共用同个subject接口,
动态代理类DynamicSubject.java
/**
* 代理处理器
*
* 该代理类的内部属性为Object类,实际使用时通过该类的构造函数DynamicSubject(Object obj)对其赋值;
* 此外,在该类还实现了invoke方法,该方法中的 method.invoke(sub,args);
* 其实就是调用被代理对象的将要被执行的方法,方法参数sub是实际的被代理对象,
* args为执行被代理对象相应操作所需的参数。
* 通过动态代理类,我们可以在调用之前或之后执行一些相关操作
*/
public class DynamicSubject implements InvocationHandler {
private Object sub; //被代理对象
public DynamicSubject() {
}
/**
* 构造方法,并初始化被代理对象
* @param obj 是被代理的对象
*/
public DynamicSubject(Object obj) {
sub = obj;
}
/**
*
* @param proxy 指代理类
* @param method 被代理的方法
* @param args 被代理的方法所需要的参数数组
* @return 在代理实例上处理方法调用并返回结果。
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理前执行的操作!");
method.invoke(sub, args);
System.out.println("代理后执行的操作!");
return null;
}
client.java
/**
* 客户端
*/
public class Client {
static public void main(String[] args) throws Throwable {
RealSubject rs = new RealSubject(); // 在这里指定被代理类
//通过被代理类对象声明一个代理类对象
InvocationHandler dynamicSubject = new DynamicSubject(rs);
Class<?> cls = rs.getClass();
// 以下是一次性生成代理类实例:
// 返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
Subject subject = (Subject) Proxy.newProxyInstance(
cls.getClassLoader(), //定义代理类的类加载器
cls.getInterfaces(), //代理类要实现的接口列表
dynamicSubject); //指派方法调用的调用处理程序:InvocationHandler对象
subject.request(); //调用代理处理器上的方法
}
}
上面用动态代理来代理了静态代理,在运行时生成Class,在生成时候给他一组接口,然后这个class就宣称实现了这些接口
上面的例子实现代理了自己写的类,其实动态代理可以代理已有的类,例如vector
public class VectorProxy implements InvocationHandler {
private Object proxyobj;
public VectorProxy(Object obj) {
proxyobj = obj;
}
public static Object factory(Object obj) {
Class<?> cls = obj.getClass();
return Proxy.newProxyInstance(cls.getClassLoader(),
cls.getInterfaces(), new VectorProxy(obj));
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("before calling " + method);
if (args != null) {
for (int i = 0; i < args.length; i++) {
System.out.println(args[i] + "");
}
}
Object object = method.invoke(proxyobj, args);
System.out.println("after calling " + method);
return object;
}
@SuppressWarnings("unchecked")
public static void main(String[] args) {
List<String> v = (List<String>) factory(new Vector<String>(10));
v.add("New");
v.add("York");
System.out.println(v);
v.remove(0);
System.out.println(v);
}
}
当做个笔记,