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


    目录

    1、什么是代理模式

    2、静态代理

    3、动态代理

    1、JDK代理

    2、cglib代理


    1、什么是代理模式

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

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

    2、静态代理

    实现静态代理的步骤:

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

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

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

    代码实现:

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

    1. public interface Singer {
    2. /**
    3. * 歌星都能唱歌
    4. */
    5. void sing();
    6. }

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

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

    1. /**
    2. * 男歌星
    3. */
    4. public class MaleSinger implements Singer{
    5. private String name;
    6. public MaleSinger(String name) {
    7. this.name = name;
    8. }
    9. /**
    10. * 歌星都能唱歌
    11. */
    12. public void sing() {
    13. System.out.println(name+"开始唱歌了……");
    14. }
    15. }

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

    1. /**
    2. * 经纪人
    3. */
    4. public class Agent implements Singer{
    5. private Singer singer;
    6. public Agent(Singer singer) {
    7. this.singer = singer;
    8. }
    9. /**
    10. * 歌星都能唱歌
    11. */
    12. public void sing() {
    13. System.out.println("节目组找过来!需要演出,谈好演出费用。。。。。");
    14. singer.sing();
    15. System.out.println("结算费用,下一次合作预约。。。。。。");
    16. }
    17. }

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

    1. public class StaticProxyTest {
    2. public static void main(String[] args) {
    3. //被代理的歌星周杰伦,他的唱歌由代理对象agent(经纪人)完成
    4. Singer singer=new MaleSinger("周杰伦");
    5. //生成代理对象,并将周杰伦传给代理对象
    6. Agent agent=new Agent(singer);
    7. //由代理对象经纪人代理唱歌
    8. agent.sing();
    9. }
    10. }

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

    3、动态代理

    1、JDK代理

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

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

    代码实现:

    接口:

    UserService

    1. /**
    2. * @author :Rk.
    3. * @date : 2022/9/10
    4. */
    5. public interface UserService {
    6. String findAllUsers();
    7. }

    接口实现类:

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

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

    1. /**
    2. * @author :Rk.
    3. * @date : 2022/9/10
    4. */
    5. public class UserTest {
    6. public static void main(String[] args) {
    7. UserServiceImpl userServiceimpl=new UserServiceImpl();
    8. UserService userService = (UserService)Proxy.newProxyInstance(UserTest.class.getClassLoader(), new Class[]{UserService.class}, new InvocationHandler() {
    9. @Override
    10. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    11. //前置增强
    12. System.out.println("在查询前进行增强!");
    13. //调用userservice中的findall方法
    14. Object invoke = method.invoke(userServiceimpl, args);
    15. //后置增强
    16. System.out.println("在查询后进行增强!");
    17. //方法返回值
    18. return invoke+"返回值";
    19. }
    20. });
    21. String allUsers = userService.findAllUsers();
    22. System.out.println(allUsers);
    23. }
    24. }

    2、cglib代理

  • 相关阅读:
    Node.js和cnpm环境搭建
    【Ajax异步请求案例&jQuery库对Ajax的封装】
    VUE3 页面路由 router
    用较新版本的Android Studio Chipmunk编译旧版本的Android 21的Sample
    VPP目的MAC检查
    十、MFC控件(二)
    DTSE Tech Talk | 云原生架构下的数字身份治理实践
    .NET Core中关于阿拉伯语环境下的坑:Input string was not in a correct format.
    LabVIEW利用局部放电分析高压电气设备状态诊断
    Kubernetes 1.24 单节点安装
  • 原文地址:https://blog.csdn.net/m0_46979453/article/details/126451938