1.1. 策略模式(Strategy Pattern)
- 代码参考
- 一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式
1.1.1. 介绍
- 应用背景:1.聚合登录的认证中心,有多种登录方式,返回需要同样的token结构,入参结构固定,登陆方式不同,所以认证中心的设计,在实现便捷扩展不同登录方式时可以只增加不同登录方式的实现。2.调度任务的异常通知方式,可以实现微信/钉钉/飞书等不同方式的通知实现
- 优点:1、应用可以自由切换2、避免使用多重条件判断3、扩展性良好
- 缺点:策略类会增多,所有策略类都会堆外暴漏
- 实现:实现同一个接口
1.1.2. 实现
创建一个定义认证操作的接口
AuthService
,聚合多种服务实现,如AppleAuthServiceImpl
,WechatAuthServiceImpl
等
- 创建一个接口 ```java import com.security.spring.web.rq.GetTokenMessageDTO; import com.security.spring.web.rs.TokenMessageDTO;
/**
@author Administrator */ public interface AuthService {
TokenMessageDTO doAuth(GetTokenMessageDTO getTokenMessageDTO); }
2. 创建实现接口的实现类
```java
import com.security.spring.auth.AuthService;
import com.security.spring.web.rq.GetTokenMessageDTO;
import com.security.spring.web.rs.TokenMessageDTO;
import org.springframework.stereotype.Service;
/**
* @author Administrator
*/
@Service
public class AppleAuthServiceImpl implements AuthService {
@Override
public TokenMessageDTO doAuth(GetTokenMessageDTO getTokenMessageDTO) {
return null;
}
}
import com.security.spring.auth.AuthService;
import com.security.spring.web.rq.GetTokenMessageDTO;
import com.security.spring.web.rs.TokenMessageDTO;
import org.springframework.stereotype.Service;
/**
* @author Administrator
*/
@Service
public class WechatAuthServiceImpl implements AuthService {
@Override
public TokenMessageDTO doAuth(GetTokenMessageDTO getTokenMessageDTO) {
return null;
}
}
- 调用方采用获取到所有实现类的方式,装载入集合内分别调用 ```java import com.security.spring.auth.AuthService; import com.security.spring.service.AuthorizationService; import com.security.spring.web.rq.GetTokenMessageDTO; import com.security.spring.web.rs.TokenMessageDTO; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference;
/**
@author Administrator */ @Service public class AuthorizationServiceImpl implements AuthorizationService, ApplicationContextAware, InitializingBean {
private ApplicationContext applicationContext; private List
authServices; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override public void afterPropertiesSet() {
Map<String, AuthService> serviceBeanMap = applicationContext.getBeansOfType(AuthService.class); if (serviceBeanMap.size() > 0) { authServices = new ArrayList<>(serviceBeanMap.values()); }
} @Override public TokenMessageDTO doAuth(GetTokenMessageDTO getTokenMessageDTO) {
AtomicReference<TokenMessageDTO> tokenMessageDTO = new AtomicReference<>(new TokenMessageDTO()); if (!CollectionUtils.isEmpty(authServices)) { authServices.forEach(authService -> { try { TokenMessageDTO messageDTO = authService.doAuth(getTokenMessageDTO); if (null != messageDTO) { tokenMessageDTO.set(messageDTO); } } catch (Exception e) { System.out.println("异常"); } }); } return tokenMessageDTO.get();
} } ```
1.1.3. 注意
实现service的实现类需要判断类型,返回异常或者空皆可处理,应用与认证中心需要改造,应用通知类则可支持多种渠道同事通知