代理 基础

代理:是一种设计模式,提供了对目标对象另外的访问方式

有些对象没法直接访问,利用代理对象间接访问

代理的好处:

1、目标对象可以间接方法文

2、代理的主要作用就是增强(代理的范围比目标对象大,可以在目标对象实现的基础上,在代理的范围内增强额外功能,即扩展目标对象的功能)

3、(当功能有些不足或者代码有些不完善)不要随意修改原有代码,如果需要修改,可以通过代理去扩展(团队开发时尤其重要)(当需要更丰富的功能时调用代理,需要本质功能调用原有方法)

代理的种类

静态代理

只能对固定类进行代理还需要修改源代码

接口实现静态代理

例子1:代购帮忙买东西

1、首先创建目标类接口(代理类目标类都要实现这个接口)

 

package Test121.Test428;
//目标接口
public interface ByClothes {
    void clothes(String size);
    void like(String x);

}

2、目标类实现接口

package Test121.Test428;
//目标类
public class ClothesFactory implements ByClothes{
    @Override
    public void clothes(String size) {
        System.out.println("已经为您制作了"+size+"尺寸的衣服");

    }

    @Override
    public void like(String x) {
        System.out.println("你最喜欢的衣服是"+x);
    }
}

3、代理类实现接口,并添加额外的功能

package Test121.Test428;

public class ClothesProxy implements ByClothes{
    //目标对象
    public ClothesFactory clothesFactory;

    public ClothesProxy(ClothesFactory clothesFactory) {
        this.clothesFactory = clothesFactory;
    }

    @Override
    public void clothes(String size) {
        //可以在目标方法实现过程中,定义一些额外的功能
        frontService();
        //这是目标对象方法
        clothesFactory.clothes(size);
        //额外功能
        endService();
    }

    @Override
    public void like(String x) {
        clothesFactory.like(x);
    }

    //售前服务
    public void frontService(){
        System.out.println("根据您的需要进行产品研发");
    }
    //售后服务
    public void endService(){
        System.out.println("产品已交付您,后续有任何问题,随时联系");
    }

}

4、测试类测试代码

package Test121.Test428;

public class Test {
    public static void main(String[] args) {
       ClothesFactory clothesFactory =  new ClothesFactory();
       ClothesProxy clothesProxy =  new ClothesProxy(clothesFactory);
       clothesProxy.clothes("xxl");
       clothesProxy.like("短袖");
    }
}

动态代理

动态代理(底层用了反射,利用反射可以实现对其他类(可以对许多类)的代理不需要改源代码)

java中一个类想拿另外一个类的全部一般来说就是继承和接口两种方式

jdk动态代理

不需要额外安装包,jdk动态代理实现代理通过(底层)接口实现

CGLIB动态代理

需要导入额外的java包,调用其中的一些方法(底层是靠继承)

例子2:代购生意做大了,创建了一个代购公司一个代购公司会代购许多不用的商品

company(jdk动态代理):

package Test121.Test428;

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

public class Company implements InvocationHandler {
    //目标对象
    private Object factory;

    public Object getFactory() {
        return factory;
    }

    public void setFactory(Object factory) {
        this.factory = factory;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //额外功能
        frontService();
        Object obj = method.invoke(factory,args);//反射实现方法
        //额外功能
        endService();
        return null;
    }
    //售前服务
    public void frontService(){
        System.out.println("根据您的需要进行产品研发");
    }
    //售后服务
    public void endService(){
        System.out.println("产品已交付您,后续有任何问题,随时联系");
    }
    //获取代购员
    public Object getProxyInstance(){
        /反射返回一个(符合后续条件的)对象
        //factory.getClass().getInterfaces()里面是一个数组形式的数据
        // 所以上面method.invoke(factory,args)调用方法其实是遍历数组知道找到名字是调用名的方法
        //Proxy.newProxyInstance(factory.getClass().getClassLoader()这里面在创建对象过程中调用了invoke方法
        return Proxy.newProxyInstance(factory.getClass().getClassLoader(),factory.getClass().getInterfaces(),this);
    }
}

测试:

package Test121.Test428;

public class Test {
    public static void main(String[] args) {
//       ClothesFactory clothesFactory =  new ClothesFactory();
//       ClothesProxy clothesProxy =  new ClothesProxy(clothesFactory);
//       clothesProxy.clothes("xxl");
//       clothesProxy.like("短袖");
        //目标对象
        ClothesFactory clothesFactory = new ClothesFactory();
        //目标对象
        ShootFactory shootFactory = new ShootFactory();
        //代购公司
        Company company = new Company();
        //为代购公司设置目标对象
        company.setFactory(shootFactory);
        //获取到了一个具体的能代购“factory(具体代购的目标对象)”的代购员
        ByShoot good1 = (ByShoot) company.getProxyInstance();//强转因为获取到的目标是Object类型
        good1.shoot("45");
    }
}

鞋子类:

package Test121.Test428;

public class ShootFactory implements ByShoot{
    @Override
    public void shoot(String size) {
        System.out.println("您买的鞋子的尺寸是:"+size);
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值