当前位置: 首页>后端>正文

spring中如何使用策略模式

这里使用登录做例子介绍如何实现登录的多种策略

spring中如何使用策略模式,第1张
file

上图是策略模式的基础模型。
?context
Context上下文角色,也叫Context封装角色,起承上启下的作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。
?Strategy
策略角色,接口类,封装相同类型策略公共方法,具体策略实现算法
?ConcreteStrategy
具体策略实现Strategy中的抽象方法,编写具体算法实现。
至此基本的策略模式就说完了,具体实现看下面在spring中我们如何实现这种策略模式来实现多种登录方式:
在spring中怎样实现Context 上下文角色
/**

  • 策略工厂,从spring上下文中提取策略

  • @author :Cai.ChangJun

  • @version 1.0.0

  • @Date : 2021/6/1
    */
    @Component
    public class LoginStrategyFactory implements InitializingBean, ApplicationContextAware {
    private final Map<LoginType, LoginService> strategyMap = new ConcurrentHashMap<>();
    private ApplicationContext appContext;

    @Override
    public void afterPropertiesSet() throws Exception {
    // 将 Spring 容器中所有的 LoginHandler 注册到 strategyMap
    appContext.getBeansOfType(LoginService.class)
    .values().forEach(hander->strategyMap.put(hander.getLoginType(),hander));
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    appContext = applicationContext;
    }

    public LoginService getStrategy(LoginType loginType) {
    return strategyMap.get(loginType);
    }
    }
    首先实现ApplicationContextAware,在spring容器启动成功后将spring上下文注入到策略工厂中appContext
    InitializingBean接口重写afterPropertiesSet 在bean初始化的时候去初始化strategyMap,从spring上下文中提取粗所有LoginService的实现类(具体策略)
    定义策略角色(Strategy)
    public interface LoginService {
    /**

    • 获取登录类型
    • @description:
    • @author Cai.ChangJun
    • @return: 登录类型
    • @version 1.0.0
    • @Date 2021/6/1 17:35
      */
      LoginType getLoginType();
/**
 * 登录并获得token一小时过期 缓存登录对象半小时过期
 * @author Cai.ChangJun
 * @param username : 用户名
 * @param password : 密码
 * @return UserDTO : 登录对象抽象
 * @version 1.0.0
 * @Date 2021/5/26 23:48
 */
UserDTO login(String username, String password);

}

具体策略实现
@Component
@Slf4j
public class PhoneChatLoginStrategy implements LoginService {
@Override
public LoginType getLoginType() {
return LoginType.PHONE;
}

@Override
public UserDTO login(String username, String password) {
    //TODO 未实现手机登录
    log.info("手机登录成功");
    return new UserDTO();
}

}
@Component
@Slf4j
public class WeChatLoginStrategy implements LoginService {
@Override
public LoginType getLoginType() {
return LoginType.WE_CHAT;
}

@Override
public UserDTO login(String username, String password) {
    //TODO 未实现微信登录
    log.info("微信登录成功");
    return new UserDTO();
}

}
每个策略我们提供了一个枚举,这样方便我们取具体策略。
public enum LoginType {
QQ,
WE_CHAT,
PHONE;
}
我们这里写了两个登录策略,具体调用:
@RestController
@RequestMapping("/user")
@Slf4j
public class PublicUserController {
@Autowired
private LoginStrategyFactory loginStrategyFactory;

 @PostMapping("/login")
public Response<UserDTO> login(@RequestBody @Validated LoginParam loginParam) {
    log.info("用户登录:{}",loginParam.getUsername());
    LoginService strategy =                                 loginStrategyFactory.getStrategy(loginParam.getLoginType());
    UserDTO login = strategy.login(loginParam.getUsername(), loginParam.getPassword());
    return new Response<>(login);
}

}
这样我们就完成了在spring中使用策略模式完成多种登录策略。

本文由博客群发一文多发等运营工具平台 OpenWrite 发布


https://www.xamrdz.com/backend/33e1940024.html

相关文章: