代理模式一篇拿捏

目录

一,代理模式:

1,代理模式的作用:

2,代理的分类:

二,静态代理:

特点:

4,静态代理执行流程:

5,面向接口编程:

三,动态代理

动态代理:

 一),JDK动态代理

1,JDK动态代理的常用工具类

1),Proxy(代理)类

产生JDK动态代理的方法:

2),Method类:

3),InvocationHandler(调用代理)接口

2,代码实现

 二),CGLib动态代理(又称子类)


一,代理模式:

目标对象不可访问,通过代理对象增强功能访问,实现访问目标对象。如:租房子,需要通过房屋中介来实现租房。目标对象:房东,代理对象:中介,客户端对象:租客。

1,代理模式的作用:

1)控制目标对象的访问

2)增强功能

2,代理的分类:

1),静态代理

2)。动态代理

        a,JDK动态代理

        b,CGLib动态代理

二,静态代理:

代理模式的一种,

特点:

1)目标对象和代理对象实现同一个业务接口

2),目标对象必须实现接口

3),代理对象在运行前就已经存在

4),能够灵活切换目标对象,无法进行功能的灵活处理(使用动态代理处理)

4,静态代理执行流程:

5,面向接口编程:

1,内部成员属性定义为接口类型,2,方法的返回值定义为接口,3,方法的参数定义为接口 

三,动态代理

动态代理:

灵活的进行功能切换的要求

静态代理:能够灵活切换目标对象,却无法进行功能的灵活处理所以要使用使用动态代理处理

代理对象在程序运行时动态在内存构建,可以灵活的进行业务切换。

 一),JDK动态代理

                a,目标对象必须实现业务接口

                b,JDK代理对象不需要实现业务接口

                c,JDK动态代理的对象,在程序运行前不存在,在程序运行时,动态的在内存构建

                d,JDK灵活的进行任务切换。

                e,本类中的自己的方法,不可以被代理

1,JDK动态代理的常用工具类

1),Proxy(代理)类

java.lang.reflect.Proxy包下的类

产生JDK动态代理的方法:

Proxy.newProxyInstance(.....)

newProxyInstance(...)的参数解读:

 ClassLoader://类加载器

Class<?>[] :目标对象实现的全部接口

InvocationHandler:代理的功能和目标对象业务的实现都在该接口下的实现类中

2),Method类:

反射用的类,用来进行对目标对象的方法的反射调用。

method.invoke();//调用方法

3),InvocationHandler(调用代理)接口

实现代理的功能和调用目标对象重写接口的方法,使用匿名内部类来实现

2,代码实现

业务接口:

public interface Service {
    void buy();
    String getName(String name);
}

目标对象1:

public class Women implements Service {
    @Override
    public void buy() {
        System.out.println("买小裙子。。。。");
    }

    @Override
    public String getName(String name) {
        System.out.println(name);
        return name;
    }
}

目标对象2:

public class Man implements Service {
    @Override
    public void buy() {
        System.out.println("买包华子。。。");
    }

    @Override
    public String getName(String name) {
        return name;
    }
}

代理工厂:程序运行时动态的创建代理对象

public class ProxyFactory {
    Service service;
    public ProxyFactory(Service service){
        this.service = service;
    }

    //获取JDK动态代理对象
    public Object getAgent(){
        return Proxy.newProxyInstance(
                service.getClass().getClassLoader(),//获得目标对象的类加载器
                service.getClass().getInterfaces(),//获得目标对象的实现的所有接口
                new InvocationHandler() {//动态代理对象的功能
                    @Override
                    public Object invoke(
                            Object proxy,//创建动态代理对象
                            Method method,//代理对象需要调用的方法
                            Object[] args//目标方法的参数
                    ) throws Throwable {
                        //代理功能
                        System.out.println("去商场");
                        //目标对象功能,args是方法运行需要的参数
                        Object invoke = method.invoke(service, args);
                        //代理功能
                        System.out.println("买到了");
                        return invoke;//返回目标方法的返回值
                    }
                }
        );
    }
}

测试:

public static void main(String[] args) {
        Service service = new Women();

        //这里不能传入实现类的匿名对象,需要先将实现类的类型提升为接口,在将替身后的对象传入,否则会出现类型转换异常
        ProxyFactory factory = new ProxyFactory(service);

        Service agent = (Service) factory.getAgent();

        //这里得到的对象类型是:class com.sun.proxy.$Proxy0
        System.out.println(agent.getClass());

        //因为他是Proxy类型的对象,所以除了这个接口的方法,实现类自己的方法是无法通过该对象来调用的
        agent.buy();
        agent.getName("张三");

    }

 二),CGLib动态代理(又称子类)

通过动态的在内存中构建子类对象,重写父类的方法,进行代理功能的增强

即在实现类没有实现接口时,通过CGLib子类代理来进行功能加强。(有点像继承)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值