Publish:

νƒœκ·Έ: , ,

μΉ΄ν…Œκ³ λ¦¬:

μ–΄λŒ‘ν„° νŒ¨ν„΄

좜처: https://refactoring.guru/ko/design-patterns/adapter

μ •μ˜

κΈ°μ‘΄ μ½”λ“œλ₯Ό ν΄λΌμ΄μ–ΈνŠΈκ°€ μ‚¬μš©ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€μ˜ κ΅¬ν˜„μ²΄λ‘œ λ°”κΏ”μ£ΌλŠ” νŒ¨ν„΄

  • ν΄λΌμ΄μ–ΈνŠΈκ°€ μ‚¬μš©ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ”°λ₯΄μ§€ μ•ŠλŠ” κΈ°μ‘΄ μ½”λ“œλ₯Ό μž¬μ‚¬μš©ν•  수 있게 ν•΄μ€€λ‹€.

μ£Όμš” ꡬ성 μš”μ†Œ

ν΄λΌμ΄μ–ΈνŠΈλŠ” Target μΈν„°νŽ˜μ΄μŠ€μ—λ§Œ μ˜μ‘΄ν•œλ‹€. 그리고 기쑴에 μ‚¬μš©ν•˜λ˜ μ½”λ“œ(Adaptee)와 Target 사이에 AdapterλΌλŠ” κ΅¬ν˜„μ²΄κ°€ μžˆλ‹€. μ—¬κΈ°μ„œ Adapter 의 역할은 기쑴에 μ‚¬μš©ν•˜λ˜ μ½”λ“œλ₯Ό ν΄λΌμ΄μ–ΈνŠΈκ°€ μ˜μ‘΄ν•˜λŠ” νƒ€μž…μ˜ 객체둜 λ³€ν™˜μ‹œμΌœ μ£ΌλŠ” 역할을 ν•œλ‹€.

μ–΄λŒ‘ν„° νŒ¨ν„΄ 적용 μ „

img.png μ–΄λŒ‘ν„° νŒ¨ν„΄ 적용 μ „ νŒ¨ν‚€μ§€ ꡬ쑰

적용 μ „ μ½”λ“œλ³΄κΈ°

LoginHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class LoginHandler {

    UserDetailsService userDetailsService;

    public LoginHandler(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    public String login(String username, String password) {
        UserDetails userDetails = userDetailsService.loadUser(username);
        if (userDetails.getPassword().equals(password)) {
            return userDetails.getUsername();
        } else {
            throw new IllegalArgumentException();
        }
    }
}

UserDetails

1
2
3
4
5
6
7
8
public interface UserDetails {

    String getUsername();

    String getPassword();

}

UserDetailsService

1
2
3
4
5
public interface UserDetailsService {

    UserDetails loadUser(String username);

}

Account

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
public class Account {

    private String name;

    private String password;

    private String email;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

}

AccountService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class AccountService {

    public Account findAccountByUsername(String username) {
        Account account = new Account();
        account.setName(username);
        account.setPassword(username);
        account.setEmail(username);
        return account;
    }

    public void createNewAccount(Account account) {

    }

    public void updateAccount(Account account) {

    }

}

μ½”λ“œλ₯Ό κ°„λž΅ν•˜κ²Œ μ‚΄νŽ΄λ³΄λ©΄, UserDetails μΈν„°νŽ˜μ΄μŠ€λŠ” μœ μ €μ˜ 이름과 λΉ„λ°€λ²ˆν˜Έλ₯Ό κ°€μ Έμ˜€λŠ” κΈ°λŠ₯을 ν•˜κ³ , UserDetailsService λŠ” μœ μ €μ˜ 이름을 λ°›μ•„ κ·Έ μœ μ € 정보λ₯Ό λ°˜ν™˜ν•˜λŠ” 역할을 ν•˜κ³ μžˆλ‹€.

κΈ°μ‘΄μ—λŠ” AccountService λ₯Ό 톡해 μœ μ € 정보λ₯Ό κ°€μ Έμ™”λŠ”λ°, 앱을 κ°œμ„ ν•˜λŠ” κ³Όμ •μ—μ„œ μƒˆλ‘œμš΄ λ°©μ‹μœΌλ‘œ(LoginHandler) ν˜ΈμΆœν•΄μ•Ό ν•˜λŠ” 상황에 놓인 것이닀.

예λ₯Ό λ“€μ–΄ security νŒ¨ν‚€μ§€(μ™ΈλΆ€ 라이브러리라고 κ°€μ •)λ₯Ό 우리 ν”„λ‘œμ νŠΈμ— ν†΅ν•©ν•˜μ—¬ μ“°κ³ μž ν•œλ‹€.
μ΄μ œλΆ€ν„° ν΄λΌμ΄μ–ΈνŠΈλŠ” UserDetailService λ₯Ό 톡해 데이터λ₯Ό 가져와야 ν•œλ‹€κ³  ν•˜λ©΄ 기쑴의 μ½”λ“œλ₯Ό λ³€κ²½ν•˜μ§€ μ•Šκ³  μ–΄λ–»κ²Œ μƒˆλ‘œμš΄ 방식과 톡합할 수 μžˆμ„κΉŒ?

그러기 μœ„ν•΄ λ¨Όμ € μ„œλ‘œ ν˜Έν™˜λ˜μ§€ μ•ŠλŠ” AccountService 와 UserDetailsService λ₯Ό μ—°κ²°ν•΄μ•Ό ν•˜κ³ , Account 와 UserDetails λ₯Ό μ—°κ²°ν•΄μ•Ό ν•œλ‹€.

μ–΄λŒ‘ν„° νŒ¨ν„΄ 적용 ν•˜κΈ°

기쑴의 μ½”λ“œ(Adaptee) λ₯Ό Target νƒ€μž…μ— 맞게 λ³€ν˜•ν•΄μ£ΌλŠ” 클래슀(Adapter)λ₯Ό μ •μ˜ν•΄μ•Ό ν•œλ‹€.

Adapter ν΄λž˜μŠ€λŠ” Adaptee λ₯Ό ν¬ν•¨ν•˜λ„λ‘ λ§Œλ“ λ‹€.

적용 ν›„ μ½”λ“œλ³΄κΈ°

AccountUserDetailsService

UserDetails κ΅¬ν˜„μ²΄μ—μ„œ 기쑴에 μ“°λ˜ AccountService 객체λ₯Ό μ‚¬μš©ν•˜λ„λ‘ ν•œλ‹€. 이 κ°μ²΄λŠ” κΈ°μ‘΄ μ„œλΉ„μŠ€μ˜ λ°˜ν™˜κ°’μ„ Target μΈν„°νŽ˜μ΄μŠ€ κ·œκ²©μ— 맞좰 λ°˜ν™˜ ν•˜λŠ” 역할을 ν•œλ‹€.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class AccountUserDetailsService implements UserDetailsService {

    private AccountService accountService;

    public AccountUserDetailsService(AccountService accountService) {
        this.accountService = accountService;
    }

    @Override
    public UserDetails loadUser(String username) {
        return new AccountUserDetails(accountService.findAccountByUsername(username));
    }
}

AccountUserDetails

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class AccountUserDetails implements UserDetails {

    private Account account;

    public AccountUserDetails(Account account) {
        this.account = account;
    }

    @Override
    public String getUsername() {
        return account.getName();
    }

    @Override
    public String getPassword() {
        return account.getPassword();
    }
}

Client

1
2
3
4
5
6
7
8
9
10
public class App {

    public static void main(String[] args) {
        AccountService accountService = new AccountService();
        UserDetailsService userDetailsService = new AccountUserDetailsService(accountService);
        LoginHandler loginHandler = new LoginHandler(userDetailsService);
        String login = loginHandler.login("keesun", "keesun");
        System.out.println(login);
    }
}

Adaptee λ₯Ό ν˜ΈμΆœν•΄ λ‚˜μ˜¨ κ²°κ³Όλ₯Ό ν΄λΌμ΄μ–ΈνŠΈκ°€ μ›ν•˜λŠ” νƒ€μž…μΈ Target νƒ€μž…μœΌλ‘œ λ°”κΏ”μ£ΌλŠ” 역할을 ν•˜λŠ”κ²ƒμ΄ Adapter λ‹€.

μž₯점과 단점

  • μž₯점
    • κΈ°μ‘΄ μ½”λ“œλ₯Ό λ³€κ²½ν•˜μ§€ μ•Šκ³  μ›ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„μ²΄λ₯Ό λ§Œλ“€μ–΄ μž¬μ‚¬μš© κ°€λŠ₯. (OCP)
    • κΈ°μ‘΄ μ½”λ“œκ°€ ν•˜λ˜ 일과 νŠΉμ • μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„μ²΄λ‘œ λ³€ν™˜ν•˜λŠ” μž‘μ—…μ„ 각기 λ‹€λ₯Έ 클래슀둜 λΆ„λ¦¬ν•˜μ—¬ 관리할 수 μžˆλ‹€. (SRP)
  • 단점
    • μƒˆ ν΄λž˜μŠ€κ°€ 생겨 λ³΅μž‘λ„κ°€ 증가할 수 μžˆλ‹€.

μžλ°”μ—μ„œ μ°Ύμ•„λ³΄λŠ” μ–΄λŒ‘ν„° νŒ¨ν„΄

Arrays.asList()

λ°°μ—΄ ν˜•νƒœ(...argsν˜•νƒœμ˜ κ°€λ³€μΈμž 포함)λ₯Ό νŒŒλΌλ―Έν„°λ‘œ λ°›μ•„ List νƒ€μž…μ„ λ°˜ν™˜ν•œλ‹€.

1
List<String> strings = Arrays.asList("a", "b", "c");

Enumeration()

1
2
3
4
// list to enumeration
Enumeration<String> enumeration = Collections.enumeration(strings);
// enumeration to list
ArrayList<String> list = Collections.list(enumeration);

io package

1
2
3
4
5
6
7
8
9
10
// io
try(InputStream is = new FileInputStream("input.txt");
    InputStreamReader isr = new InputStreamReader(is);
    BufferedReader reader = new BufferedReader(isr)) {
    while(reader.ready()) {
        System.out.println(reader.readLine());
    }
} catch (IOException e) {
    throw new RuntimeException(e);
}

μŠ€ν”„λ§μ—μ„œ μ°Ύμ•„λ³΄λŠ” μ–΄λŒ‘ν„° νŒ¨ν„΄

HandlerAdapter

Spring MVC μ—λŠ” DispatcherServlet μ΄λΌλŠ” ν”„λ‘ νŠΈ 컨트둀러 역할을 ν•˜λŠ” ν•Έλ“€λŸ¬ ν΄λž˜μŠ€κ°€ μžˆλ‹€. λ‚΄λΆ€ λ©”μ†Œλ“œ 쀑 각 상황에 λ§žλŠ” ν•Έλ“€λŸ¬λ₯Ό μ„ νƒν•˜λŠ” λ©”μ†Œλ“œκ°€ μžˆλŠ”λ° 이 뢀뢄에 μ–΄λŒ‘ν„° νŒ¨ν„΄μ΄ μ μš©λ˜μ–΄ μžˆλ‹€.

doDispatch λ©”μ†Œλ“œ μ‚΄νŽ΄λ³΄κΈ°

DispatcherServlet - doDispatch

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
  HttpServletRequest processedRequest = request;
  HandlerExecutionChain mappedHandler = null;
  boolean multipartRequestParsed = false;
  WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

  try {
    try {
      ModelAndView mv = null;
      Exception dispatchException = null;

      try {
        processedRequest = this.checkMultipart(request);
        multipartRequestParsed = processedRequest != request;
        mappedHandler = this.getHandler(processedRequest);
        if (mappedHandler == null) {
          this.noHandlerFound(processedRequest, response);
          return;
        }

        // 졜근 μš”μ²­μ— λ§žλŠ” μ μ ˆν•œ μ–΄λŒ‘ν„°λ₯Ό κ°€μ Έμ˜¨λ‹€.
        HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
        String method = request.getMethod();
        boolean isGet = "GET".equals(method);
        if (isGet || "HEAD".equals(method)) {
          long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
          if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
            return;
          }
        }

        if (!mappedHandler.applyPreHandle(processedRequest, response)) {
          return;
        }

        // μ–΄λŒ‘ν„°λ₯Ό μ‹€ν–‰ν•΄ Target νƒ€μž…μœΌλ‘œ λ³€ν™˜ν•œλ‹€.
        mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
        if (asyncManager.isConcurrentHandlingStarted()) {
          return;
        }

        this.applyDefaultViewName(processedRequest, mv);
        mappedHandler.applyPostHandle(processedRequest, response, mv);
      } catch (Exception var20) {
        Exception ex = var20;
        dispatchException = ex;
      } catch (Throwable var21) {
        Throwable err = var21;
        dispatchException = new NestedServletException("Handler dispatch failed", err);
      }

      this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
    } catch (Exception var22) {
      Exception ex = var22;
      this.triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
    } catch (Throwable var23) {
      Throwable err = var23;
      this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", err));
    }

  } finally {
    if (asyncManager.isConcurrentHandlingStarted()) {
      if (mappedHandler != null) {
        mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
      }
    } else if (multipartRequestParsed) {
      this.cleanupMultipart(processedRequest);
    }

  }
}

ν•΄λ‹Ή λ©”μ†Œλ“œ 쀑간에 보면

1
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());

이런 μ½”λ“œκ°€ μžˆλŠ”λ°, ν•΄λ‹Ή μš”μ²­μ— λ§žλŠ” ν•Έλ“€λŸ¬λ₯Ό μ²˜λ¦¬ν•  수 μžˆλŠ” μ–΄λŒ‘ν„°λ₯Ό κ°€μ Έμ˜€λŠ” μ½”λ“œλ‹€. κ·Έ ν›„ μ ν•©ν•œ μ–΄λŒ‘ν„°λ₯Ό 톡해 ModelAndView 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” μ½”λ“œκ°€ μžˆλ‹€.

1
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

μ–΄λŒ‘ν„°μ˜ handle λ©”μ†Œλ“œμ˜ 결과둜 Target νƒ€μž…(ModelAndView) λ₯Ό λ°˜ν™˜ν•œλ‹€. λ‹€μ–‘ν•œ μ’…λ₯˜μ˜ ν•Έλ“€λŸ¬μ— λŒ€ν•΄ μΌκ΄€λœ λ°©μ‹μœΌλ‘œ ModelAndViewλ₯Ό λ°˜ν™˜ν•΄ μ€€λ‹€.

ν•΄λ‹Ή λ©”μ†Œλ“œλ₯Ό 듀어가보면 μ–΄λŒ‘ν„° 용 μΈν„°νŽ˜μ΄μŠ€κ°€ μžˆλ‹€.

1
2
3
4
5
6
7
8
public interface HandlerAdapter {
  boolean supports(Object var1);

  @Nullable
  ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;

  long getLastModified(HttpServletRequest var1, Object var2);
}

그리고 κ·Έ 쀑 μš”μ²­μ— λŒ€ν•΄ @RequestMapping μ–΄λ…Έν…Œμ΄μ…˜μ„ μ²˜λ¦¬ν•˜λŠ” ν•Έλ“€λŸ¬μΈ RequestMappingHandlerAdapter 이 μžˆλ‹€λŠ” 것을 μ•Œ 수 μžˆλ‹€.

λ‹€μ–‘ν•œ μ’…λ₯˜μ˜ μš”μ²­μ„ μ²˜λ¦¬ν•˜λŠ” ν•Έλ“€λŸ¬κ°€ μžˆλ‹€.

μ–΄λŒ‘ν„° νŒ¨ν„΄ vs. λ°μ½”λ ˆμ΄ν„° νŒ¨ν„΄

μ•„λž˜λŠ” μ–΄λŒ‘ν„° νŒ¨ν„΄κ³Ό λ°μ½”λ ˆμ΄ν„° νŒ¨ν„΄μ„ κ°„λž΅ν•˜κ²Œ λΉ„κ΅ν•œ 것이닀.

차이점 비ꡐ 클릭

μ–΄λŒ‘ν„° νŒ¨ν„΄ (Adapter Pattern)

μ •μ˜: μ–΄λŒ‘ν„° νŒ¨ν„΄μ€ ν˜Έν™˜λ˜μ§€ μ•ŠλŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό 가진 클래슀λ₯Ό ν˜Έν™˜λ˜λ„λ‘ λ³€ν™˜ν•΄μ£ΌλŠ” νŒ¨ν„΄. 주둜 κΈ°μ‘΄ 클래슀λ₯Ό μž¬μ‚¬μš©ν•˜λ©΄μ„œλ„ μΈν„°νŽ˜μ΄μŠ€κ°€ λ§žμ§€ μ•Šμ„ λ•Œ μ‚¬μš©ν•œλ‹€.

λͺ©μ : κΈ°μ‘΄ 클래슀의 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ›ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€λ‘œ λ³€ν™˜ν•˜μ—¬ μ„œλ‘œ ν˜Έν™˜λ˜μ§€ μ•ŠλŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό 가진 ν΄λž˜μŠ€λ“€μ΄ ν•¨κ»˜ λ™μž‘ν•  수 있게 ν•œλ‹€.

ꡬ쑰:

  • 타깃 μΈν„°νŽ˜μ΄μŠ€(Target Interface): ν΄λΌμ΄μ–ΈνŠΈκ°€ μ‚¬μš©ν•˜κ³ μž ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€.
  • μ–΄λŒ‘ν„°(Adapter): 타깃 μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜κ³  μ–΄λŒ‘ν‹°(Adaptee)의 λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ λ³€ν™˜μ„ μˆ˜ν–‰.
  • μ–΄λŒ‘ν‹°(Adaptee): μ–΄λŒ‘ν„°μ— μ˜ν•΄ λ³€ν™˜λ˜λŠ” κΈ°μ‘΄ 클래슀.

λ°μ½”λ ˆμ΄ν„° νŒ¨ν„΄ (Decorator Pattern)

μ •μ˜: λ°μ½”λ ˆμ΄ν„° νŒ¨ν„΄μ€ 객체에 λ™μ μœΌλ‘œ μƒˆλ‘œμš΄ 행동을 μΆ”κ°€ν•  수 있게 ν•΄μ£ΌλŠ” νŒ¨ν„΄. 상속을 톡해 κΈ°λŠ₯을 ν™•μž₯ν•˜λŠ” λŒ€μ‹  λ°μ½”λ ˆμ΄ν„° 객체λ₯Ό 톡해 κΈ°λŠ₯을 μΆ”κ°€ν•œλ‹€.

λͺ©μ : 객체의 κΈ°λŠ₯을 λ™μ μœΌλ‘œ ν™•μž₯ν•  수 μžˆλ„λ‘ ν•˜λ©°, 상속보닀 μœ μ—°ν•œ κΈ°λŠ₯ ν™•μž₯을 μ œκ³΅ν•œλ‹€.

ꡬ쑰:

  • μ»΄ν¬λ„ŒνŠΈ(Component): κΈ°λ³Έ μΈν„°νŽ˜μ΄μŠ€λ‘œ, λ°μ½”λ ˆμ΄ν„°μ™€ ꡬ체 μ»΄ν¬λ„ŒνŠΈκ°€ κ΅¬ν˜„ν•œλ‹€.
  • ꡬ체 μ»΄ν¬λ„ŒνŠΈ(Concrete Component): κΈ°λ³Έ κΈ°λŠ₯을 κ΅¬ν˜„ν•˜λŠ” 클래슀.
  • λ°μ½”λ ˆμ΄ν„°(Decorator): μ»΄ν¬λ„ŒνŠΈ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λ©°, μ»΄ν¬λ„ŒνŠΈ 객체λ₯Ό ν¬ν•¨ν•œλ‹€. 좔가적인 κΈ°λŠ₯을 μ •μ˜ν•  수 μžˆλ‹€.
  • ꡬ체 λ°μ½”λ ˆμ΄ν„°(Concrete Decorator): λ°μ½”λ ˆμ΄ν„° 클래슀λ₯Ό ν™•μž₯ν•˜μ—¬ ꡬ체적인 κΈ°λŠ₯을 μΆ”κ°€ν•œλ‹€.

μ–΄λŒ‘ν„° νŒ¨ν„΄μ„ κ³΅λΆ€ν•˜λ©΄μ„œ λ°μ½”λ ˆμ΄ν„° νŒ¨ν„΄κ³Ό λΉ„μŠ·ν•˜λ‹€λŠ” λŠλ‚Œμ„ λ°›μ•˜λ‹€. ν•©μ„±μ΄λΌλŠ” 방식(λ©€λ²„λ³€μˆ˜)으둜 클래슀λ₯Ό ν™•μž₯ν•˜κ³  있기 λ•Œλ¬Έμ— κ·Έλ ‡κ²Œ 느꼈던 것 κ°™λ‹€.

λ³΄λŠ” μ‹œκ°μ— 따라 μ–΄λŒ‘ν„°νŒ¨ν„΄μ΄ 될 μˆ˜λ„ 있고, λ°μ½”λ ˆμ΄ν„°νŒ¨ν„΄μ΄ 될 μˆ˜λ„ μžˆλ‹€. λͺ©μ μ— 따라 λΆ„λ₯˜λ₯Ό ν•΄λ³΄μžλ©΄, κΈ°μ‘΄ μ½”λ“œμ™€μ˜ ν˜Έν™˜μ— λͺ©μ μ΄ μžˆλ‹€λ©΄ μ–΄λŒ‘ν„°νŒ¨ν„΄μœΌλ‘œ λ³Ό 수 있고, κΈ°μ‘΄μ½”λ“œμ˜ κΈ°λŠ₯을 ν™•μž₯ν•œλ‹€λŠ” κ°œλ…μœΌλ‘œ λ³Έλ‹€λ©΄ λ°μ½”λ ˆμ΄ν„° νŒ¨ν„΄μœΌλ‘œ λ³Ό 수 μžˆλ‹€.

예λ₯Ό λ“€μ–΄, μœ„μ—μ„œ μ˜ˆμ‹œλ‘œ λ“  AccountUserDetailsService λ‚˜ AccountUserDetails 와 같은 μ–΄λŒ‘ν„°λ₯Ό μƒˆλ‘œ λ§Œλ“€μ§€ μ•Šκ³  기쑴의 ν΄λž˜μŠ€μ— Target νƒ€μž…μ„ κ΅¬ν˜„ν•˜λŠ” λ°©ν–₯으둜 κ°„λ‹€λ©΄ μƒˆλ‘œμš΄ κΈ°λŠ₯을 μΆ”κ°€ν•˜λŠ” κ°œλ…μœΌλ‘œ λ³Ό μˆ˜λ„ μžˆλŠ” 것이닀.

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
public class AccountService implements UserDetailService{

    public Account findAccountByUsername(String username) {
        Account account = new Account();
        account.setName(username);
        account.setPassword(username);
        account.setEmail(username);
        return account;
    }

    public void createNewAccount(Account account) {

    }

    public void updateAccount(Account account) {

    }
    
    // μƒˆλ‘­κ²Œ μΆ”κ°€λœ κΈ°λŠ₯
    @Override
    public UserDetail loadUser(String username) {
      return findAccountByUsername(username);
    }

}

각각의 방법은 μž₯단점이 μžˆμ–΄ ν”„λ‘œμ νŠΈμ˜ 상황을 κ³ λ €ν•΄ μ„ νƒν•˜λ©΄ 될 것 κ°™λ‹€.

λ””μžμΈνŒ¨ν„΄μ— λŒ€ν•œ 생각

사싀 λ””μžμΈνŒ¨ν„΄ μ΄λΌλŠ” 것은 νŠΉμ •ν•œ 상황을 효율적으둜 ν•΄κ²°ν•˜κΈ° μœ„ν•œ 말 κ·ΈλŒ€λ‘œ μΌμ’…μ˜ νŒ¨ν„΄λ“€μ— λΆˆκ³Όν•˜κΈ° λ•Œλ¬Έμ— νŒ¨ν„΄ μžμ²΄μ— 맀λͺ°λ˜κΈ° λ³΄λ‹€λŠ” 각 νŒ¨ν„΄μ˜ νŠΉμ§•μ„ μ΄ν•΄ν•œ ν›„, μ§€κΈˆ λ‚˜μ˜ 상황에 λ§žλŠ” μ μ ˆν•œ νŒ¨ν„΄μ„ 선택할 수 μžˆλŠ” μ‹œμ•Όλ₯Ό κ°–λŠ” 것이 더 μ€‘μš”ν•˜λ‹€κ³  μƒκ°ν•œλ‹€. 그러기 μœ„ν•΄μ„  λ‹€μ–‘ν•œ 예제λ₯Ό μ ‘ν•˜λ©΄μ„œ μ™œ ν•΄λ‹Ή νŒ¨ν„΄μ„ μ‚¬μš©ν–ˆμ„κΉŒμ— λŒ€ν•΄ 슀슀둜 μΆ©λΆ„νžˆ κ³ λ―Όν•΄λ³΄λŠ” μ‹œκ°„μ„ κ°€μ Έμ•Ό ν•  것 κ°™λ‹€.

λ°©λ¬Έν•΄ μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€! λŒ“κΈ€,지적,ν”Όλ“œλ°± μ–Έμ œλ‚˜ ν™˜μ˜ν•©λ‹ˆλ‹€πŸ˜Š

λŒ“κΈ€λ‚¨κΈ°κΈ°