目录
- 一级目录
- 二级目录
- 三级目录
- 代理模式最佳实践
- demo1 静态代理:
- demo2 动态代理:
一级目录
二级目录
三级目录
代理模式最佳实践
代理模式是一种结构型设计模式,它通过引入一个代理对象来控制对另一个对象的访问。在Spring框架中,代理模式常用于延迟初始化、访问控制、日志记录、事务管理等场景。以下是一个使用Spring AOP(面向方面编程)来实现代理模式的示例,而不是传统的静态代理或动态代理。
demo1 静态代理:
定义一个MessageService接口和它的实现
public interface MessageService {void sendMessage(String msg);
}public class RealMessageService implements MessageService {@Overridepublic void sendMessage(String msg) {System.out.println("Sending message: " + msg);}
}
然后,我们创建一个代理类,它包装了RealMessageService并添加了额外的功能:
public class MessageServiceProxy implements MessageService {private RealMessageService realService;@Overridepublic 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 {@Beanpublic 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;@Autowiredpublic 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 {@Overridepublic 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 {@Beanpublic RealMessageService realMessageService() {return new RealMessageService();}@Beanpublic 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;@Autowiredpublic MessageClient(MessageService messageService) {this.messageService = messageService;}public void sendMessage(String msg) {messageService.sendMessage(msg);}
}
在这个例子中,我们使用Spring的AOP来创建MessageService的代理。当调用sendMessage方法时,切面中的通知会被执行,从而实现了代理模式。
请注意,这个例子假设RealMessageService类实现了MessageService接口。如果这些条件不满足,你可能需要调整代码以处理异常情况。
此外,这个例子没有处理切面可能抛出的异常。在生产环境中,你可能需要添加更多的错误处理代码来确保切面可以被成功执行。
这个例子假设所有的切面类都在同一个包下。如果它们不在同一个包下,你需要使用全限定类名。