Java设计模式--静态代理与动态代理

Java静态代理与动态代理

1.静态代理(通过接口实现类去代理另一个接口实现类)

  • 解释:静态代理就比如租房这个事件,房东是真实对象,中介是代理对象,我是客户,我要去找中介才能租房子(比自己找更方便,还有中介服务)。房东实现租房接口能出租房子,中介实现租房接口也能出租房子,但是房子是房东的,中介只能代理,于是中介只能靠房东(真实对象)实现出租房子,当然中介还可以加上其它自己想要的操作
  • 例子:

租房接口:

package com.lxf.demo01;

//租房接口
public interface Rent {
    public void rent();
}

房东(真实对象):

package com.lxf.demo01;


//房东对象
public class Host implements Rent{
    @Override
    public void rent() {
        System.out.println("房东要出租房子");
    }
}

中介(代理对象)

package com.lxf.demo01;

public class Proxy implements Rent{
    private Host host;

    public Proxy() {
    }
    //将真实对象赋给host
    public setHost(Host host) {
        this.host = host;
    }

    @Override
    public void rent() {
        //看房子
        seeHouse();
        //签合同
        singContract();
        //出租房子
        host.rent();
        //收费
        fare();
    }
    //看房
    public void seeHouse(){
        System.out.println("中介带你看房");
    }
    //收中介费
    public void fare(){
        System.out.println("中介收中介费");
    }
    //签合同
    public void singContract(){
        System.out.println("签租赁合同");
    }
}

客户(测试实例):

package com.lxf.demo01;

public class Client {
    public static void main(String[] args) {
        //房东:真实对象
        Host host=new Host();
        //代理:代理对象
        Proxy proxy = new Proxy();
		//将真实对象传给代理对象
        proxy.setHost(Host host);
        //找中介租房(中介在中间捞油水)
        proxy.rent();
    }
}

2.动态代理

  • 解释:再次看租房这个事件,房东是真实对象,中介是代理对象,我是客户,我要去找中介才能租房子。房东实现租房接口能出租房子,此时中介不实现租房接口,建一个生成代理类的类(通过set或者构造函数接收真实对象,生成代理类),生成代理类的类实现InvocationHandler接口,然后将房东丢入生成代理类的类生成中介代理类,这个于是中介代理类就可以出租房子了,当然中介还可以加上其它自己想要的操作
  • 例子:

租房接口:

package com.lxf.demo01;

//租房接口
public interface Rent {
    public void rent();
}

房东接口:

package com.lxf.demo01;

//房东对象
public class Host implements Rent{
    @Override
    public void rent() {
        System.out.println("房东要出租房子");
    }
}

生成代理类的类:

package com.lxf.demo03;

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

//实现代理类生成的类
public class ProxyInvocationHandler implements InvocationHandler {
    //被代理的真实对象
    private Rent rent;

    //设置真实对象
    public void setRent(Rent rent) {
        this.rent = rent;
    }

    //生成代理类
    public Object getProxy(){
//Proxy.newProxyInstance(ClassLoader loader,Class<?>[] Ingterfaces,InvocationHandler h);
       //第一个参数:真实对象的类加载器
        //第二个参数:真实对象实现的所有的接口
        //第三个参数: 接口,传递一个匿名内部类对象
        return Proxy.newProxyInstance(rent.getClass().getClassLoader(),
                                  rent.getClass().getInterfaces(),this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //动态代理的本质:使用反射机制实现!
        //实现方法
        Object result = method.invoke(rent, args);

        return result;
    }


}

客户(测试实例):

package com.lxf.demo03;

public class Client {
    public static void main(String[] args) {
        //真实角色
        Host host = new Host();

        //获取代理角色的类
        ProxyInvocationHandler handler = new ProxyInvocationHandler();
        //将真实角色加入
        handler.setRent(host);
        //代理角色
        Rent proxy = (Rent) handler.getProxy();

		//实现方法
        proxy.rent();
    }
}

3.静态代理与动态代理异同

  • 相同处:都是通过代理对象去实现方法,并且都可以加上其它操作。

  • 不同处:静态代理是通过代理对象实现类去代理真实对象实现类,而动态代理是通过一个生成代理类的类去生成代理对象,动态代理的好处在于"很灵活"。静态代理的代理对象是一个实际的类,要是真实对象发生改变,代理对象也要改。而动态代理的代理对象通过类产生,而不完全依赖于类,当真实对象发生改变也没事,甚至可以将生成代理类的类改成万能类:

    package com.lxf.demo04;
    
    import com.lxf.demo03.Rent;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    //实现代理类生成的类
    public class ProxyInvocationHandler implements InvocationHandler {
        //被代理的接口
        private Object target;
    
        public void setTarget(Object target) {
            this.target = target;
        }
    
        //生成代理类
        public Object getProxy(){
           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(method.getName());
            //动态代理的本质:使用反射机制实现!
            Object result = method.invoke(target, args);
    
            return result;
        }
    
    }
    

    动态代理分类补充:

    1. 基于接口:jdk动态代理类
    2. 基于类:cglib动态代理类
    3. java字节码实现:javassist(用在JBoss服务器上)

猜你喜欢

转载自blog.csdn.net/Inmaturity_7/article/details/106533922
今日推荐