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

目录

一级目录

二级目录

三级目录

代理模式最佳实践

<<interface>> Subject +request() RealSubject +request() Proxy +request()

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

demo1 静态代理:

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

java 复制代码
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并添加了额外的功能:

java 复制代码
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为代理:

java 复制代码
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:

java 复制代码
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 动态代理:

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

java 复制代码
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)来实现代理逻辑:

java 复制代码
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的配置类中启用切面和自动代理:

java 复制代码
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:

java 复制代码
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接口。如果这些条件不满足,你可能需要调整代码以处理异常情况。

此外,这个例子没有处理切面可能抛出的异常。在生产环境中,你可能需要添加更多的错误处理代码来确保切面可以被成功执行。

这个例子假设所有的切面类都在同一个包下。如果它们不在同一个包下,你需要使用全限定类名。

相关推荐
杨充10 小时前
10.可测试性实战设计
设计模式·开源·代码规范
杨充11 小时前
9.重构十二式的实战
设计模式·开源·代码规范
杨充11 小时前
6.设计原则的全景图
设计模式·开源·全栈
杨充11 小时前
2.面向对象的特性
设计模式
杨充11 小时前
7.SOLID原则案例汇
设计模式·开源·全栈
杨充11 小时前
8.反模式与坏味道
设计模式·开源·代码规范
杨充11 小时前
3.接口vs抽象类比较
设计模式
咖啡八杯14 小时前
文法、BNF与AST
java·设计模式·解释器模式·ast·文法
咖啡八杯1 天前
GoF设计模式——解释器模式
java·后端·spring·设计模式