`
wjjbfq
  • 浏览: 80004 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

代理的例子(静态代理和动态代理)

 
阅读更多

代理分为静态代理和动态代理。代理就想找局长办事,你不认识局长,但你认识局长秘书,你可以找局长秘书来完成对局长的操作。

代理模式一般涉及到的角色有

§抽象角色:声明真实对象和代理对象的共同接口
§代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装
§真实角色:代理角色所代表的真实对象,是我们最终要引用的对象

 

静态代理:

// 抽象角色

abstract public class Subject

{

    abstract public void request();

}

 

//真实角色:实现了Subject的request()方法

public class RealSubject extends Subject
{

    public RealSubject()
    {
    }

    public void request()
    {
        System.out.println("From real subject.");
    }

}

 

//代理角色

public class ProxySubject extends Subject

{
    private RealSubject realSubject; // 以真实角色作为代理角色的属性

    public ProxySubject()
    {
    }

    public void request() // 该方法封装了真实对象的request方法

    {
        preRequest();

        if (realSubject == null)
        {
            realSubject = new RealSubject();
        }

        realSubject.request(); // 此处执行真实对象的request方法

        postRequest();
    }

    private void preRequest()
    {

        // something you want to do before requesting

    }

    private void postRequest()
    {

        // something you want to do after requesting

    }

}

 

//客户端调用

public class Client
{
    public static void main(String[] args)
    {
        Subject sub = new ProxySubject();

        sub.request();
    }
}

 

 

动态代理:

动态代理步骤:

1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法
2.创建被代理的类以及接口
3.通过Proxy的静态方法
newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 创建一个代理
4.通过代理调用方法

//抽象角色(之前是抽象类,此处应改为接口): 

public interface Subject
{
    abstract public void request();
}

 

//具体角色

public class RealSubject implements Subject
{

    public RealSubject()
    {
    }

    public void request()
    {
        System.out.println("From real subject.");
    }

}

 

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

//代理处理器 

/**
 * 该代理类的内部属性为Object类,实际使用时通过该类的构造函数DynamicSubject(Object obj)对其赋值;
 * 此外,在该类还实现了invoke方法,该方法中的 method.invoke(sub,args);
 * 其实就是调用被代理对象的将要被执行的方法,方法参数sub是实际的被代理对象,
 * args为执行被代理对象相应操作所需的参数。
 * 通过动态代理类,我们可以在调用之前或之后执行一些相关操作
 */

public class DynamicSubject implements InvocationHandler
{
    private Object sub;

    public DynamicSubject()
    {
    }

    public DynamicSubject(Object obj)
    {
        sub = obj;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        System.out.println("before calling " + method);

        method.invoke(sub, args);

        System.out.println("after calling " + method);

        return null;
	}

}

 

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

//客户端

public class Client
{
	static public void main(String[] args) throws Throwable
	{

		RealSubject rs = new RealSubject(); // 在这里指定被代理类
		InvocationHandler ds = new DynamicSubject(rs);
		Class<?> cls = rs.getClass();

		// 以下是一次性生成代理

		Subject subject = (Subject) Proxy.newProxyInstance(
				cls.getClassLoader(), cls.getInterfaces(), ds);

		subject.request();
	}
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics