代理模式

来源:互联网 发布:java数组添加元素 编辑:程序博客网 时间:2024/06/03 19:58
这篇博客只是我个人见解,有不对的地方忘大家指出。
为什么要有代理模式。
     代理模式是当客户端不想,或者不能直接访问某个对象的时候,我们为其提供一个代理对象,客户通过这个代理对象来访问委托对象。代理分为静态代理,动态代理。静态代理是代理类在编译器就已经存在,被编译成 .class 文件;动态代理是在运行期的时候通过反射机制来获取委托对象。
静态代理
     静态代理中代理类和真实类要实现一样的接口。对于这个,我的理解是,在应用代理的时候,我们通过代理类调用的方法从根本上来说还是真实类的方法,代理类实现了真实类的接口,给客户端的感觉他就是在访问真实类的对象。
     静态代理是在编译期就决定了代理对象是哪一个,因此,当有多个委托对象的时候,我们最好要有多个代理对象(这里的最好是因为,只应用一个代理对象也是可以的,但是所有的委托都使用同一个代理,对客户端来说并不友好,就像是每一个经纪人都只对一个演员负责,如果对多个人负责的话容易混乱)。从这里也可以看出静态代理的一个缺点——对于每一个委托对象都要有一个代理,当代理很多的时候,代码的整体结构就会很庞大,很乱。此外,代理和委托类都实现了同样的接口,如果接口中添加了方法,除了委托需要实现这个方法,代理类也要实现,这样代码的维护会很复杂。
一个静态代理的例子:
//interface
public interface MoveService {

    void noticeMoveType();
}

//impl
public class MoveServiceImpl implements MoveService {
    @Override
    public void noticeMoveType() {
        System.out.println("today's move is GongFu");
    }
}

//proxy  代理类也要实现MoveService接口,在方法中调用真实类的方法
public class ProxyAll implements  MoveService {

    private MoveService moveService;

    public ProxyAll(MoveService moveService){
        this.moveService = moveService;
    }

    @Override
    public void noticeMoveType() {
        System.out.println("notice move type start");
        moveService.noticeMoveType();
        System.out.println("notice move type end");
    }
}

// client  客户端实现
public class ProxyStart {

    public static void main(String[] args){
        ProxyAll proxyAll = new ProxyAll(new MoveServiceImpl());
        proxyAll.noticeMoveType();
    }
}
动态代理:
     动态代理是在程序运行的过程中通过反射来得到委托类的对象,然后调用其方法,从这里就可以看出动态代理的好处了:只有一个代理类,我们只要在运行的过程中指定委托就可以了。提高了代码的重用性。
一个动态代理的例子
//UserService
public interface UserService {

    void userSaySomething();
}

//UserServiceImpl
public class UserUserServiceImpl implements UserService {
    @Override
    public void userSaySomething() {
        System.out.println("this is real userService");
    }
}

//Proxy
public class ProxyAll implements InvocationHandler {

    private Object target;

    public ProxyAll(Object target){
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("——start——");
        Object result = method.invoke(target, args);
        System.out.println("——end——");

        return result;
    }

    // 生成代理对象
    public Object getProxy() {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Class<?>[] interfaces = target.getClass().getInterfaces();
        return java.lang.reflect.Proxy.newProxyInstance(loader, interfaces, this);
    }
}

//ProxyTest
public class ProxyTest {

    public static void main(String[] args) {
        UserService userService = new UserUserServiceImpl();
       
        ProxyAll handler = new ProxyAll(userService);
        UserService userServiceProxy = (UserService)handler.getProxy();
        userServiceProxy.userSaySomething();
    }
}
     实现动态代理,代理类要实现InvocationHandler中的invoke方法。
/**
*@param proxy  被代理的对象
*@param method 要调用的方法
*@param args   执行方法是需要的参数
*/
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;

/**
*@param loader 类加载器
*@param interfaces  得到全部的接口
*@param h  得到InvocationHandler接口子类的实例
*@return Object  返回代理的实例
*/
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException
原创粉丝点击