在工作中一次不同场景登录调用不同免登的情况下,我想出用工厂类显然可以更加灵活的解决代码冗余的问题,具体实现如下

首先,引入基本的工厂存储类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import com.atom.common.spring.AbstractBaseLogger;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public abstract class BaseHandlerFactory<T> extends AbstractBaseLogger {
private Map<String, T> handlers = new HashMap();

public BaseHandlerFactory() {
}

public void register(String key, T handler) {
this.handlers.put(key, handler);
}

public T get(String key) {
return this.handlers.get(key);
}

public T exist(String key) {
return this.handlers.containsKey(key) ? this.handlers.get(key) : this.getDefaultHandler(key);
}

public void del(String key) {
this.handlers.remove(key);
}

protected T getDefaultHandler(String key) {
return null;
}

public Set<String> keys() {
return this.handlers.keySet();
}

protected T getDefaultHandler() {
return null;
}

建立工厂实现类的方法规范

让他们都实现该方法达到多态调用的目的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import com.sso.server.model.user.ThirdUserLoginRes;

/**
* @program: sso-server
* @author: Ren blog.igotu.top
* @create: 2024-11-04 17:18
* @description:
**/
public interface OauthHandler {

ThirdUserLoginRes login(String code, String redirect_uri);

}

创建一个免登的工厂类

其中静态字符属性可加在枚举接口中,保证数据是无状态的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import com.atom.common.factory.BaseHandlerFactory;

/**
* @program: sso-server
* @author: Ren blog.igotu.top
* @create: 2024-11-04 17:23
* @description:
**/
public class OauthHandlerFactory extends BaseHandlerFactory<OauthHandler> {
public static String GOAUTH_INSTANCE = "gOauthInstance";
public static String APPOAUTH_INSTANCE = "appOauthInstance";
public static String WXOAUTH_INSTANCE = "wxOauthInstance";

private static OauthHandlerFactory instance = new OauthHandlerFactory();

public static OauthHandlerFactory getInstance() {
return instance;
}

}

实现他们的工厂类,并将他们对应的代理名称注册在自己的初始化方法里,实现规范方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* @program: sso-server
* @author: Ren blog.igotu.top
* @create: 2024-11-04 17:18
* @description:
**/
@Component
public class AppOauthHandlerImpl implements OauthHandler {

// 使用此init初始化,将工厂类的调用名称注册进工厂内存存储中
@PostConstruct
public void init() {
OauthHandlerFactory.getInstance().register(OauthHandlerFactory.APPOAUTH_INSTANCE, this);
}

// 该方法中实现登录的业务
@Override
public ThirdUserLoginRes login(String code, String returnUri) {
// xxx...
}
}

接下来就可以用该工厂类多态规范化的调用,不同实现方法的登录业务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
@RestController
@RequestMapping("/oauth")
@Slf4j
public class LoginOAuthController extends BaseController {

@Value("${oauth.app_redirect_uri}")
private String appReturnUri;
@Value("${oauth.gserver_redirect_uri}")
private String gServerReturnUri;
@Value("${oauth.wechat_redirect_uri}")
private String wechatReturnUri;

@RequestMapping("/callback/{soft}")
public void callbackCenter(@PathVariable("soft") String soft, @RequestParam("code") String code, HttpServletResponse response) throws IOException {
// 收到的授权码
log.info("Received authorization code: " + code);

switch (soft) {
case "app":
response.sendRedirect(
OauthHandlerFactory.getInstance()
.exist(OauthHandlerFactory.APPOAUTH_INSTANCE)
.login(code, appReturnUri).getUrl());
case "server":
response.sendRedirect(
OauthHandlerFactory.getInstance()
.exist(OauthHandlerFactory.GOAUTH_INSTANCE)
.login(code, gServerReturnUri).getUrl());
case "wechat":
response.sendRedirect(
OauthHandlerFactory.getInstance()
.exist(OauthHandlerFactory.WXOAUTH_INSTANCE)
.login(code, wechatReturnUri).getUrl());
default:
throw new BusinessException(ResultCode.PARAMS_NOT_EXIST);
}
}

}