代理模式(简要介绍)

代理的目的:
(1)控制访问目标对象
(2)增强功能实现
理解案例:
商场请明星唱歌,需要找明星助理解决,不能直接联系到明星。助理同时要给明星安排行程,和商场协商价钱。
实现:
(1)静态代理
(2)动态代理

1.1静态代理

商场Service
//业务功能请明星唱歌
public interface Service {
    void Sing();
}
明星实现类
//明星唱歌:目标对象(无法直接访问)
// 目标对象必须实现接口
public class SuperStarZhou implements Service {
    @Override
    public String Show(int age) {
        System.out.println("周杰伦在跳舞");
        return "show method";
    }
}
静态代理类
//代理对象在程序运行前就已经存在
// 能够灵活的进行目标对象的切换,却无法进行功能的灵活处理(使用动态代理解决此问题)
public class Agent implements Service {
    private  Service target;
    public Agent(Service target) {
        this.target = target;
    }
    @Override
    public void Sing() {
        System.out.println("---助理交接业务---");//增强功能实现
        System.out.println("---助理交接明星----");
        target.Sing();//控制访问目标对象
        System.out.println("-----助理收费-------");
    }
 }

优点分析:
(1)面向接口编程
类中的成员变量设计为接口,方法的形参设计为接口,方法的返回值设计为接口,调用时接口指向实现类.
体现:

private  Service target;
public Agent(Service target) {
        this.target = target;
}

可以使用一个代理类来处理各种实现业务接口的实现类。
举例:商场请其他明星来唱歌,这几个明星一个公司的。有一个总助理。因此只需要在助理构造注入的时候传入具体是那个明星来唱歌就行了

 @Test
    public void test1(){
            Service agent =new Agent(new SuperStarXue());
            Service agent1 =new Agent(new SuperStarZhang());
            agent.Sing();
            agent1.Sing();
    }

缺点分析:
当商场需要明星唱歌的同时还可以跳舞,rap,打篮球?

商场Service
//业务功能请明星唱歌
public interface Service {
    void Sing();
    void Dance();
    void Rap();
    void playBasketball();
}

代理类和明星类两个都是实现了商场类接口需求的具体实现类,因此当商场需求增加时,代理类和明星类都要实现商场其他需求的接口。因此代码量急剧增加。
解决:动态代理

2.1 动态代理

代理对象在程序运行的过程中动态在内存构建.可以灵活的进行业务功能的切换.
(1)JDK动态代理
(2)CGLib动态代理
JDK动态代理
特点:
1.代理对象不需要实现业务接口
2.代理对象是在程序运行时动态的在内存中构建
3.目标对象必须要实现接口,才可以使用JKD的动态代理
代码实现:
a)Proxy:生成代理对象
b)Method:目标方法的调用
c)InvocationHandler:增强功能实现

public class ProxyFactory {
    //类中的成员变量设计为接口,目标对象
    Service target;
    //传入目标对象
    public ProxyFactory(Service target) {
        this.target = target;
    }
    //返回动态代理对象
    public Object getAgent(){
        return Proxy.newProxyInstance(
                //ClassLoader loader, 类加载器,完成目标对象的加载
                target.getClass().getClassLoader(),
                //Class<?>[] interfaces,目标对象实现的所有接口
                target.getClass().getInterfaces(),
                //InvocationHandler h,实现代理功能的接口 ,传入的是匿名内部实现
                new InvocationHandler() {
                    @Override
                    public Object invoke(
                            //创建代理对象Object proxy,
                            Object proxy,
                            //method就是目标方法sing(),show()
                            Method method,
                            //目标方法的参数
                            Object[] args
                    ) throws Throwable {
                        //代理功能
                        System.out.println("---助理交接业务---");
                        System.out.println("---助理交接明星----");
                        //主业务功能实现
                        //target.sing();还是写死了方法的调用, 不成
                        //sing(),show(),one()
                        Object obj=method.invoke(target,args);
                        System.out.println("-----助理收费-------");
                        return obj;//切记:这个是目标方法的返回值
                    }
                }) ;
    }
}

生成代理对象
调用Proxy.newProxyInstance()生成动态代理对象

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
 /-------------------------------------------------------------------------------------------
 ClassLoader loader:类加载器,加载目标对象(如这里的业务具体实现类:某一个明星)
 Class<?>[] interfaces:目标对象实现的所有接口(唱跳rap篮球)
 InvocationHandler h:实现代理功能,当外部目标对象方法被调用时,此接口的实现类被执行(这里用匿名类实现)
 	public Object invoke(Object proxy, Method method, Object[] args)
 	throws Throwable;
 		Object proxy:创建代理对象Object proxy
 		Method method:method就是目标方法sing(),dance(),rap(),playBasketball()
 		Object[] args://目标方法的参数
 		在抛出的Throwable中进行增强功能的实现,和通过方法的反射实现获得目标中实现的方法
 		最后返回obj,返回的是目标对象中所有方法的返回值。(例如:rap()方法在调用时返回 hip hop对象)
                            

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

b站动力节点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值