• 设计模式最佳实践代码总结 - 结构型设计模式篇 - 代理模式最佳实践


    一级目录

    二级目录

    三级目录

    代理模式最佳实践

    «interface»
    Subject
    +request()
    RealSubject
    +request()
    Proxy
    +request()

    代理模式是一种结构型设计模式,它通过引入一个代理对象来控制对另一个对象的访问。在Spring框架中,代理模式常用于延迟初始化、访问控制、日志记录、事务管理等场景。以下是一个使用Spring AOP(面向方面编程)来实现代理模式的示例,而不是传统的静态代理或动态代理。

    demo1 静态代理:

    定义一个MessageService接口和它的实现

    public interface MessageService {
        void sendMessage(String msg);
    }
    
    public class RealMessageService implements MessageService {
        @Override
        public void sendMessage(String msg) {
            System.out.println("Sending message: " + msg);
        }
    }
    

    然后,我们创建一个代理类,它包装了RealMessageService并添加了额外的功能:

    public class MessageServiceProxy implements MessageService {
        private RealMessageService realService;
    
        @Override
        public void sendMessage(String msg) {
            // 在调用实际服务之前和之后的额外操作
            System.out.println("Before sending message");
            if (realService == null) {
                realService = new RealMessageService();
            }
            realService.sendMessage(msg);
            System.out.println("After sending message");
        }
    }
    

    现在,我们可以在Spring的配置类中注册MessageService bean为代理:

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class AppConfig {
    
        @Bean
        public MessageService messageServiceProxy() {
            return new MessageServiceProxy();
        }
    }
    

    最后,我们可以在Spring的上下文中使用这个MessageService bean:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MessageClient {
        private final MessageService messageService;
    
        @Autowired
        public MessageClient(MessageService messageService) {
            this.messageService = messageService;
        }
    
        public void sendMessage(String msg) {
            messageService.sendMessage(msg);
        }
    }
    

    以上为传统模式代理模式写法,代理模式在spring aop得到广泛实践,下面示例为切面编程的简单实践。

    demo2 动态代理:

    首先,我们定义一个接口和实现类:

    public interface MessageService {
        void sendMessage(String msg);
    }
    
    public class RealMessageService implements MessageService {
        @Override
        public void sendMessage(String msg) {
            System.out.println("Sending message: " + msg);
        }
    }
    

    接下来,我们定义一个切面(Aspect)来实现代理逻辑:

    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    
    @Aspect
    public class MessageServiceAspect {
        @Pointcut("execution(* com.example.service.RealMessageService.sendMessage(..))")
        public void messageServiceMethods() {}
    
        @Around("messageServiceMethods()")
        public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
            System.out.println("Before sending message");
            Object result = joinPoint.proceed();
            System.out.println("After sending message");
            return result;
        }
    }
    

    在上面的切面中,我们定义了一个切点(Pointcut)来匹配RealMessageService类的sendMessage方法,并在该方法前后添加了通知(Advice)来实现日志记录。
    现在,我们可以在Spring的配置类中启用切面和自动代理:

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableAspectJAutoProxy;
    import org.springframework.context.annotation.ComponentScan;
    
    @Configuration
    @EnableAspectJAutoProxy
    @ComponentScan(basePackages = "com.example")
    public class AppConfig {
    
        @Bean
        public RealMessageService realMessageService() {
            return new RealMessageService();
        }
    
        @Bean
        public MessageServiceAspect messageServiceAspect() {
            return new MessageServiceAspect();
        }
    }
    

    最后,我们可以在Spring的上下文中使用这个MessageService bean:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MessageClient {
    
        private final MessageService messageService;
    
        @Autowired
        public MessageClient(MessageService messageService) {
            this.messageService = messageService;
        }
    
        public void sendMessage(String msg) {
            messageService.sendMessage(msg);
        }
    }
    

    在这个例子中,我们使用Spring的AOP来创建MessageService的代理。当调用sendMessage方法时,切面中的通知会被执行,从而实现了代理模式。
    请注意,这个例子假设RealMessageService类实现了MessageService接口。如果这些条件不满足,你可能需要调整代码以处理异常情况。
    此外,这个例子没有处理切面可能抛出的异常。在生产环境中,你可能需要添加更多的错误处理代码来确保切面可以被成功执行。
    这个例子假设所有的切面类都在同一个包下。如果它们不在同一个包下,你需要使用全限定类名。

  • 相关阅读:
    【算法题】从数量最多的堆取走礼物
    Java基础面试题【4】
    进阶C++__STL__set/ multiset和map/ multimap使用方法
    怎么查找和自己专业有关的英文文献?
    Java:实现判断链表是否有一个循环算法(附完整源码)
    域名 DNS 信息查询 API 数据接口
    SOLIDWORKS® 2024 新功能 - 3D CAD
    软件项目管理 7.4.3.进度计划编排-时间压缩法
    《机器学习》(周志华) 第5章 神经网络 学习心得 笔记
    SpringSecurity单体项目最佳实践
  • 原文地址:https://blog.csdn.net/weixin_42439274/article/details/143305992