代理模式(proxy)

发布时间:2024年01月05日

1.代理模式?

1.1创建工程

1.2代理模式的介绍

作用:通过代理可以控制访问某个对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理。(即: AOP的微观实现!)

核心角色

  • 抽象角色(接口):定义公共对外方法

  • 真实角色(周杰伦):实现抽象角色,定义真实角色所要实现的业务逻辑

  • 代理角色(代理人):实现抽象角色,是真实角色的代理,通过调用真实角色的方法来完成业务逻辑,并可以附加自己的操作

?2.

2.静态代理

2.1抽象角色

package com.by.proxy.staticProxy;

public interface Star {
    /**
     * 面谈
     */
    void confer();
    /**
     * 签合同
     */
    void signContract();
    /**
     * 订票
     */
    void bookTicket();
    /**
     * 唱歌
     */
    void sing();
    /**
     * 收钱
     */
    void collectMoney();
}

?2.2真正角色(周杰伦)

package com.by.proxy.staticProxy;

public class RealStar implements Star{
    @Override
    public void confer() {

    }

    @Override
    public void signContract() {

    }

    @Override
    public void bookTicket() {

    }

    @Override
    public void sing() {
        System.out.println("天青色等烟雨,而我在等你,炊烟袅袅升起,隔江千万里....");
    }

    @Override
    public void collectMoney() {

    }
}

2.3代理角色(经纪人)

package com.by.proxy.staticProxy;

public class proxyStar implements Star{
    private Star star;

    public proxyStar(Star star) {
        this.star = star;
    }

    @Override
    public void confer() {
        System.out.println("面谈");
    }

    @Override
    public void signContract() {
        System.out.println("签合同");
    }

    @Override
    public void bookTicket() {
        System.out.println("订机票");
    }

    @Override
    public void sing() {
        star.sing();
    }

    @Override
    public void collectMoney() {
        System.out.println("收尾款");
    }
}

?2.4测试

package com.by.proxy.staticProxy;

public class Client {
    public static void main(String[] args) {
        Star star = new proxyStar(new RealStar());
        star.sing();
        star.bookTicket();
        star.collectMoney();
        star.confer();
        star.signContract();
    }
}

?2.5结果

2.6静态代理的缺点

  1. 代理类和实现类实现了相同的接口,这样就出现了大量的代码重复。

  2. 代理对象只服务于一种类型的对象。如果要服务多类型的对象,例如代码是只为UserService类的访问提供了代理,但是还要为其他类如DeptService类提供代理的话,就需要我们再次添加代理DeptService的代理类

3.jdk动态代理

?3.1抽象角色

package com.by.proxy.jdkProxy;

public interface Star {
    void sing();
}

?3.2真正角色

package com.by.proxy.jdkProxy;

public class RealStar implements Star{
    @Override
    public void sing() {
        System.out.println("天青色等烟雨,而我在等你,炊烟袅袅升起,隔江千万里......");
    }
}

?3.3代理工厂

package com.by.proxy.jdkProxy;

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

public class ProxyFactory {
    /**
     * 要代理的真实角色
     */
    private Object realObj;
    public ProxyFactory(Object realObj){
        this.realObj=realObj;
    }
    //创建代理工厂,生成代理类proxy{.面谈.签合同.订机票【调用杰哥唱歌】.收尾款}
   public Object getObjectProxy(){
       /**
        * ClassLoader loader,类加载器
        * Class<?>[] interfaces,公共接口
        * InvocationHandler h)调用invoke方法
        */
          return Proxy.newProxyInstance(realObj.getClass().getClassLoader(),
               realObj.getClass().getInterfaces(),
               new InvocationHandler() {
                   @Override
                   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                       //代理类既要调用真实角色,还要处理自己的事务
                       System.out.println("面谈");
                       System.out.println("签合同");
                       System.out.println("订机票");
                       Object result = method.invoke(realObj, args);
                       System.out.println("收尾款");
                       return result;
                   }
               });
    }

}

?3.4测试

package com.by.proxy.jdkProxy;

public class Client {
    public static void main(String[] args) {
       Star star = (Star) new ProxyFactory(new RealStar()).getObjectProxy();
       star.sing();
    }
}

3.5结果

4.Cglib动态代理

?cglib与动态代理最大的区别就是:

  • 使用jdk动态代理的对象必须实现一个接口

  • 使用cglib代理的对象则无需实现接口

CGLIB是第三方提供的包,所以需要引入jar包的坐标:

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2.2</version>
</dependency>

?如果你已经有spring-core的jar包,则无需引入,因为spring中包含了cglib。

4.1真正角色

package com.by.proxy.CglibProxy;

public class RealStar{

	public void sing() {
		System.out.println("RealStar(周杰伦本人).sing()");
	}
}

4.2代理角色

4.3测试

package com.by.proxy.CglibProxy;

//测试类
public class Client {
    public static void main(String[] args) {
        //获取代理对象
        RealStar proxyObject = 
            (RealStar) new ProxyFactory(new RealStar()).getProxyObject();
        proxyObject.sing();
    }
}

5.总结

1)静态代理
? ? ? ? ? ? 角色:
? ? ? ? ? ? ? ? 公共接口:Star
? ? ? ? ? ? ? ? 真实角色:RealStar(真实角色.唱歌)
? ? ? ? ? ? ? ? 代理角色:ProxyStar(代理角色.面谈.订机票.签合同.[调周杰伦唱歌].收尾款)
? ? ? ? ? ? ? ? 客户类:Client(客户.调代理角色)

? ? ? ? ? ? 缺陷:1.大量代码重复 2.只能代理Star类型的对象
? ? ? ? 2)jdk动态代理
? ? ? ? ? ? 角色:
? ? ? ? ? ? ? ? 公共接口:Star
? ? ? ? ? ? ? ? 真实角色:RealStar(真实角色.唱歌)
? ? ? ? ? ? ? ? 代理工厂:ProxyFactroy{生成ProxyStar(代理角色.面谈.订机票.签合同.[调周杰伦唱歌].收尾款)}
? ? ? ? ? ? ? ? 客户类:Client(客户.调代理角色)
? ? ? ? 3)Cglib动态代理
? ? ? ? ? ? cglib和jdk动态代理的区别:cglib真实角色没有接口

文章来源:https://blog.csdn.net/qq_62965575/article/details/135395717
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。