设计模式---代理模式(结构型)

目录

1、什么是代理模式

2、静态代理

3、动态代理

1、JDK代理

2、cglib代理


1、什么是代理模式

        代理模式为某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。这样做的好处:扩展目标对象的功能,核心功能是方法增强。代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。简单的说就是,我们在访问实际对象时,是通过代理对象来访问的,代理模式就是在访问实际对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途。

       代理有不同的形式:静态代理和动态代理。其中动态代理包括 JDK代理和cglib代理。

2、静态代理

实现静态代理的步骤:

  1. 代理类跟目标类需要实现同一个接口的方法,

  2. 在代理类中定义目标的对象,编写代理方法,在代理方法中使用目标对象的方法及一些扩展操作。

  3. 创建代理类对象和目标对象,将目标对象传给代理类对象,代理类对象使用代理方法。

代码实现:

        1、首先,我们创建一个Siner接口。这个接口就是歌星(被代理类),和经纪人(代理类)的公共接口,他们都有上唱歌的行为。这样,歌星唱歌就可以让经纪人来代理执行,经纪人可以在歌星唱歌前、后进行增强。

public interface Singer {

    /**
     * 歌星都能唱歌
     */
    void sing();
}

         2、创建被代理对象实现接口,完成具体的业务逻辑

        MaleSinger 类实现Singer接口。MaleSinger 可以具体实唱歌的动作:

/**
 * 男歌星
 */
public class MaleSinger implements Singer{

    private String name;

    public MaleSinger(String name) {
        this.name = name;
    }

    /**
     * 歌星都能唱歌
     */
    public void sing() {
        System.out.println(name+"开始唱歌了……");
    }
}

        3、 创建代理类实现接口,完成委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。

/**
 * 经纪人
 */
public class Agent implements Singer{
    
    private Singer singer;

    public Agent(Singer singer) {
        this.singer = singer;
    }

    /**
     * 歌星都能唱歌
     */
    public void sing() {
        System.out.println("节目组找过来!需要演出,谈好演出费用。。。。。");
        singer.sing();
        System.out.println("结算费用,下一次合作预约。。。。。。");
    }
}

        4、客户端使用操作与分析 

public class StaticProxyTest {
    public static void main(String[] args) {

        //被代理的歌星周杰伦,他的唱歌由代理对象agent(经纪人)完成
        Singer singer=new MaleSinger("周杰伦");
        //生成代理对象,并将周杰伦传给代理对象
        Agent agent=new Agent(singer);
        //由代理对象经纪人代理唱歌
        agent.sing();
    }
}

          缺点:代理对象需要和目标对象实现一样的接口,所以会产生很多的代理类一旦增加方法,目标类和代理类都要进行维护。 

3、动态代理

1、JDK代理

        在java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口通过这个类和这个接口可以生成JDK动态代理类和动态代理对象JDK动态代理的前提是必须有接口,JDK 动态代理会为每个业务接口动态生成相应的代理类实现,并加载到 JVM 中,然后创建对应的代理实例对象。

        JDK 动态代理的实现原理:动态创建代理类,然后通过指定类加载器进行加载。

代码实现:

接口:

UserService

/**
 * @author :Rk.
 * @date : 2022/9/10
 */
public interface UserService {

    String findAllUsers();

}

接口实现类:

/**
 * @author :Rk.
 * @date : 2022/9/10
 */
public class UserServiceImpl implements UserService {
    @Override
    public String findAllUsers() {
        System.out.println("查询所有用户");
        return "查询到用户:12345";
    }
}

使用jdk动态代理实现代理类:

/**
 * @author :Rk.
 * @date : 2022/9/10
 */
public class UserTest {
    public static void main(String[] args) {
        UserServiceImpl userServiceimpl=new UserServiceImpl();
        UserService userService = (UserService)Proxy.newProxyInstance(UserTest.class.getClassLoader(), new Class[]{UserService.class}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //前置增强
                System.out.println("在查询前进行增强!");
                //调用userservice中的findall方法
                Object invoke = method.invoke(userServiceimpl, args);
                //后置增强
                System.out.println("在查询后进行增强!");
                //方法返回值
                return invoke+"返回值";
            }
        });

        String allUsers = userService.findAllUsers();
        System.out.println(allUsers);
    }
}

2、cglib代理

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rk..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值