๋ฐ˜์‘ํ˜•

๐Ÿš— ์‹ฑ๊ธ€ํ†ค์ด๋ž€?


์‹ฑ๊ธ€ํ†ค์€ ์ธ์Šคํ„ด์Šค๋ฅผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์˜ค์ง ํ•˜๋‚˜๋งŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ํด๋ž˜์Šค๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

์˜ˆ๋กœ ์Šคํ”„๋ง ๊ธฐ๋ณธ ๋นˆ์ด ์‹ฑ๊ธ€ํ†ค์ด๋‹ค. ์Šคํ”„๋ง ๋นˆ์„ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์ด์ ์€

๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ ๋ณ„๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ์ด์œ ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋ฌด์˜๋ฏธํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

๋ณ„๊ฐœ๋กœ ์Šคํ”„๋ง์—์„œ์˜ ๋นˆ ์‹ฑ๊ธ€ํ†ค์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „๋ฐ˜์˜ ์‹ฑ๊ธ€ํ†ค์ด ์•„๋‹Œ

์Šคํ”„๋ง ApplicationContext ๋‚ด์—์„œ์˜ ์‹ฑ๊ธ€ํ†ค์„ ์˜๋ฏธํ•œ๋‹ค.

์ฆ‰, new XXXService();๋ฅผ ํ•˜๋ฉด ์ƒˆ๋กœ์šด ๊ฐ์ฒด๊ฐ€ Context ๋ฐ–์— ์ƒ์„ฑ์ด ๋œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

๐Ÿš— ์‹ฑ๊ธ€ํ†ค์˜ ์ฃผ์˜์ 


์‹ฑ๊ธ€ํ†ค์€ ๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ณต์œ ํ•˜๋Š” ์ž์›์ด๊ธฐ ๋•Œ๋ฌธ์— ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๊ฐ€ ์กด์žฌํ•˜๋ฉด ์•ˆ๋œ๋‹ค.

๋งŒ์•ฝ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋ฅผ ์˜๋„์น˜ ์•Š๊ฒŒ ํ•˜๋‚˜์˜ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ณ€๊ฒฝํ•˜๊ฒŒ ๋˜๋ฉด ๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „ํŒŒ๋˜๊ธฐ

๋•Œ๋ฌธ์ด๋‹ค.

๐Ÿš— ์‹ฑ๊ธ€ํ†ค์˜ ๋‹จ์ 


ํ…Œ์ŠคํŠธ ์‹œ mock์œผ๋กœ ๋Œ€์ฒดํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต๋‹ค. ๊ทธ๋ž˜์„œ ์Šคํ”„๋ง์—์„œ๋„ ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ๊ถŒ์žฅํ•œ๋‹ค.

๐Ÿš— ์‹ฑ๊ธ€ํ†ค ๋ณด์ฆ ๋ฐฉ๋ฒ• 2๊ฐ€์ง€


์‹ฑ๊ธ€ํ†ค์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ์‹์€ ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€์ด๋‹ค.

  • public static final ํ•„๋“œ ๋ฐฉ์‹์˜ ์‹ฑ๊ธ€ํ†ค
  • ์ •์  ํŒฉํ† ๋ฆฌ ๋ฐฉ์‹์˜ ์‹ฑ๊ธ€ํ†ค

๐Ÿš— public static final ํ•„๋“œ ๋ฐฉ์‹


์ด ๋ฐฉ์‹์€ public static final๋กœ ๋ฏธ๋ฆฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ , private์œผ๋กœ ๋” ์ด์ƒ ์ƒ์„ฑํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋ง‰์•„์„œ

์‹ฑ๊ธ€ํ†ค์ž„์„ ๋ณด์ฆํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

public class Elvis {

  private Elvis() {}

  public static final Elvis INSTANCE = new Elvis();

  public void method() {
    System.out.println("Elvis.method");
  }
}

๐Ÿฅฌ ๋ฆฌํ”Œ๋ ‰์…˜ ๋ฌธ์ œ์ 

ํ•˜์ง€๋งŒ ์ด ๋ฐฉ์‹์€ ๋ฆฌํ”Œ๋ ‰์…˜์œผ๋กœ ์ ‘๊ทผํ•˜๋ฉด private ์ƒ์„ฑ์ž์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ์˜ when์ ˆ์ฒ˜๋Ÿผ reflection์„ ์‚ฌ์šฉํ•˜๋ฉด ์‹ฑ๊ธ€ํ†ค์ด ๋ณด์žฅ๋˜์ง€ ์•Š๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค.

@Test
void ๋ฆฌํ”Œ๋ ‰์…˜์œผ๋กœ_private_์ƒ์„ฑ์ž๋กœ_์ธ์Šคํ„ด์Šค_์ƒ์„ฑ()
    throws
    NoSuchMethodException,
    InvocationTargetException, InstantiationException, IllegalAccessException {
  // given
  Elvis instance = Elvis.INSTANCE;

  // when
  Constructor<Elvis> constructor = Elvis.class.getDeclaredConstructor();
  constructor.setAccessible(true);
  Elvis reflectionInstance = constructor.newInstance();

  // then
  assertThat(instance).isNotSameAs(reflectionInstance);
}

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๊ฒ ์ง€๋งŒ, ์ฑ…์—์„œ ์†Œ๊ฐœํ•˜๋Š” ๋‚ด์šฉ์€ ์ƒ์„ฑ์ž์—์„œ ๊ฐ์ฒด๊ฐ€ ๋˜ ์ƒ์„ฑ๋˜๋ ค ํ•˜๋ฉด,

์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋Š” ๋ฐฉ๋ฒ•์„ ์•ˆ๋‚ดํ•˜๊ณ  ์žˆ๋‹ค. ๊ทธ ๋ฐฉ๋ฒ•์€ ์ฑ…์— ์žˆ์ง€๋Š” ์•Š์ง€๋งŒ, ์•„๋ž˜์™€ ๊ฐ™์ด ํ•ด๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.

private Elvis() {
  if (Objects.nonNull(INSTANCE)) {
    throw new RuntimeException("์‹ฑ๊ธ€ํ†ค์ด๋ฏ€๋กœ ์ƒ์„ฑ ๋ถˆ๊ฐ€!!");
  }
}

์ด๋ฅผ ํ…Œ์ŠคํŠธ ํ•ด๋ณด๋ฉด Runtime Exception์œผ๋กœ ๋ฆฌํ”Œ๋ ‰์…˜ ๊ณต๊ฒฉ์ด ์‹คํŒจํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

@Test
void ๋ฆฌํ”Œ๋ ‰์…˜_๋ฐฉ์–ด()
    throws
    NoSuchMethodException,
    InvocationTargetException, InstantiationException, IllegalAccessException {
  // given
  Elvis instance = Elvis.INSTANCE;

  // when
  Constructor<Elvis> constructor = Elvis.class.getDeclaredConstructor();
  constructor.setAccessible(true);

  // then
  constructor.newInstance(); // RutimeException
}

ํ•˜์ง€๋งŒ Assertj๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฒ€์ฆ์„ ํ•˜๋ฉด ์กฐ๊ธˆ ๋‹ค๋ฅด๊ฒŒ InvocationTargetException์„ ๋ฐœ์ƒ ์‹œํ‚จ๋‹ค.

@Test
void ๋ฆฌํ”Œ๋ ‰์…˜_๋ฐฉ์–ด()
    throws
    NoSuchMethodException,
    InvocationTargetException, InstantiationException, IllegalAccessException {
  // given
  Elvis instance = Elvis.INSTANCE;

  // when
  Constructor<Elvis> constructor = Elvis.class.getDeclaredConstructor();
  constructor.setAccessible(true);

  // then
  assertThatThrownBy(constructor::newInstance)
      .isInstanceOf(InvocationTargetException.class);
}

java doc์—์„œ๋Š” InvocationTargetException์„ ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค๋ช…ํ•˜๊ณ  ์žˆ๋‹ค.

InvocationTargetException์€ ํ˜ธ์ถœ๋œ ๋ฉ”์„œ๋“œ ๋˜๋Š” ์ƒ์„ฑ์ž๊ฐ€ ๋˜์ง„ ์˜ˆ์™ธ๋ฅผ ๋ž˜ํ•‘ํ•˜๋Š” ์„ ํƒ๋œ ์˜ˆ์™ธ์ž…๋‹ˆ๋‹ค.

๐Ÿฅฌ ์žฅ์ 

  • ์ฝ”๋“œ๊ฐ€ ์•„์ฃผ ๊ฐ„๊ฒฐํ•˜๋‹ค.

๐Ÿš— ์ •์  ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ ๋ฐฉ์‹


์ด ๋ฐฉ์‹์€ ์ •์  ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ํ™œ์šฉํ•ด์„œ ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

public class Elvis {

  private static final Elvis INSTANCE = new Elvis();
  private Elvis() {}

  public static Elvis getInstance() {
    return INSTANCE;
  }
}

๐Ÿฅฌ API๋ฅผ ๋ฐ”๊พธ์ง€ ์•Š๊ณ ๋„ ๋ณ€๊ฒฝ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์‹ฑ๊ธ€ํ†ค์ด ์•„๋‹ˆ๋„๋ก ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

  • public static final ํ•„๋“œ ๋ฐฉ์‹์—์„œ ์‹ฑ๊ธ€ํ†ค์ด ์•„๋‹ˆ๋„๋ก ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ ๋˜์–ด์•ผ ํ•œ๋‹ค.
    ์•„๋ž˜์˜ ์ฝ”๋“œ๊ฐ€ public static final์˜ ์ฝ”๋“œ์ธ๋ฐ ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๋Š” Evlis.INSTANCE๋ฅผ ์ฐธ์กฐํ•˜๊ณ 
    ์žˆ์—ˆ์ง€๋งŒ, new Elvis()๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ ๋˜์–ด์•ผ ํ•œ๋‹ค.

      public static final Elvis INSTANCE = new Elvis();
  • ์ •์  ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ ๋ฐฉ์‹์€ ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€๋งŒ ์ˆ˜์ •ํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ ๋ณ€๊ฒฝ์—†์ด
    ๋ณ€๊ฒฝ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

      public static Elvis getInstance() {
        return new Elvis();
      }

๐Ÿฅฌ ์ •์  ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๋„ค๋ฆญ ์‹ฑ๊ธ€ํ†ค ํŒฉํ† ๋ฆฌ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ??????

๐Ÿฅฌ Supplier๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด Supplier๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ธ๋ฐ

์–ด๋–ค ์ƒํ™ฉ์—์„œ Supplier์™€ ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค๊ณ  ํ•  ๊ฒฝ์šฐ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

Supplier<Elvis> elvisSupplier = Elvis::getInstance;

๐Ÿฅฌ ๋‹จ์ 

์ƒํ™ฉ์— ๋งž์ถฐ ์“ฐ๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋”ฑํžˆ ๋‹จ์ ์ด๋ผ๊ณ  ๋ณผ๊ฑด ์—†์ง€๋งŒ ์•„๋ฌด๋ž˜๋„

public static final ๋ฐฉ์‹์— ๋น„ํ•ด์„œ๋Š” ๊ฐ„๊ฒฐํ•˜์ง€ ์•Š๋‹ค๋Š” ์ ์ด๋‹ค.

์ •๋ฆฌ

ํ•˜์ง€๋งŒ ๊ฒฐ๊ตญ ์ด๋Ÿฌํ•œ ์žฅ์ ๋“ค์ด ํ•„์š”์—†๋‹ค๋ฉด public static final ๋ฐฉ๋ฒ•์„ ์“ฐ๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๊ฐ„๊ฒฐํ•˜๋‹ค.

๐Ÿš— ์ง๋ ฌํ™” ์ฃผ์˜์ 


์œ„์—์„œ ์‚ดํŽด๋ณธ ๋‘ ๋ฐฉ๋ฒ•์€ ๋ชจ๋‘ ์ง๋ ฌํ™”์— ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ์—ญ์ง๋ ฌํ™” ํ•  ๋•Œ ๊ฐ™์€ ํƒ€์ž…์˜ ์ธ์Šคํ„ด์Šค๊ฐ€

์—ฌ๋Ÿฌ๊ฐœ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, ์‹ฑ๊ธ€ํ†ค์ด ๊นจ์ง„๋‹ค. ๊ทธ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ์ธ์Šคํ„ด์Šค ํ•„๋“œ์—

transient(์ง๋ ฌํ™” ๋ชฉ๋ก์—์„œ ์ œ์™ธ)๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  readResolve() ๋ฉ”์„œ๋“œ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค.

์ •ํ™•ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ๋Œ€๋žต์ ์œผ๋กœ Serializable ์ธํ„ฐํŽ˜์ด์Šค์—์„œ readResolve๋ฅผ ์ด์šฉํ•ด์„œ ์—ญ์ง๋ ฌํ™”๋ฅผ

ํ•œ๋‹ค๊ณ  ํ•˜๋Š”๋ฐ ์ด๋ ‡๊ฒŒ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•˜๋ฉด, ์˜ค๋ฒ„๋ผ์ด๋”ฉ๋œ ๋ฉ”์„œ๋“œ๋ฅผ ์ฝ๊ธฐ ๋•Œ๋ฌธ์— ์—ญ์ง๋ ฌํ™”์— ์•ˆ์ „ํ•˜๋‹ค๊ณ  ํ•œ๋‹ค.

์‹ค์ œ๋กœ Serializable์€ ๋นˆ ์ธํ„ฐํŽ˜์ด์Šค์ด์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ์–ด๋–ค ๋ฉ”์„œ๋“œ๊ฐ€ ์กด์žฌํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ๊ทธ ์ค‘ ํ•˜๋‚˜๊ฐ€

๋ฐ”๋กœ readResolve()์ธ ๊ฒƒ์ด๋‹ค.

public static transient final Elvis INSTANCE = new Elvis();

@Serial
public Object readResolve() {
    return INSTANCE;
}
  • @Serial: ์ง๋ ฌํ™” ์—ญ์ง๋ ฌํ™”์˜ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ๋ฉ”์„œ๋“œ๊ฐ€ ๋งž๋Š”์ง€ ํ™•์ธํ•ด์ฃผ๋Š” ์• ๋…ธํ…Œ์ด์…˜์ด๋‹ค.
    ๋งŒ์•ฝ readRsolve1()์ด๋ผ๊ณ  ์„ ์–ธํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ warning์„ ๋„์šด๋‹ค.

    Annotated member is not a part of the serialization mechanism

๐Ÿš— readResolve ๋ฉ”์„œ๋“œ


ํ•ด๋‹น ๋‚ด์šฉ์€ ์‹ฑ๊ธ€ํ†ค์„ ๊ธฐ์ค€์œผ๋กœ ์„ค๋ช…ํ•œ๋‹ค.

readResolve ๋ฉ”์„œ๋“œ๋ž€ ๋ฌด์—‡์ธ๊ฐ€

์ฐธ๊ณ : oracle document

์—ญ์ง๋ ฌํ™” ์‹œ readResolve ๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธํ–ˆ๋‹ค๋ฉด, ์ธ์Šคํ„ด์Šค๋ฅผ ์ง์ ‘ ํ†ต์ œํ•  ์ˆ˜ ์žˆ๋‹ค.

์ธ์Šคํ„ด์Šค๋ฅผ ํ†ต์ œํ•œ๋‹ค๋Š” ๊ฒƒ์€ ์‹ฑ๊ธ€ํ†ค์„ ์˜ˆ๋กœ ๋“ค ์ˆ˜ ์žˆ๋‹ค.

์—ญ์ง๋ ฌํ™” ์‹œ readResolve ๋ฉ”์„œ๋“œ๊ฐ€ ์„ ์–ธ๋˜์ง€ ์•Š์œผ๋ฉด ๋งค๋ฒˆ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ์„ ์–ธ๋˜์–ด ์žˆ๋‹ค๋ฉด, ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ’์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.

๊ทธ ์›๋ฆฌ๋Š” ObjectInpuStream์ด ์•„๋ž˜์™€ ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

  1. ์ŠคํŠธ๋ฆผ์„ ์—ญ์ง๋ ฌํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ˜ํ™˜ํ•  ์ค€๋น„๋ฅผ ํ•œ๋‹ค.
  2. readResolve ๋ฉ”์„œ๋“œ๊ฐ€ ์„ ์–ธ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
  3. ์ •์˜๋œ ๊ฒฝ์šฐ readResolve ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•œ๋‹ค.
  4. ๊ทธ๋ ‡๋‹ค๊ณ  ํ•ด๋„ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋Š” ์ƒ์„ฑ์ด๋˜๋Š”๋ฐ ์ด๋Š” GC ๋Œ€์ƒ์ด ๋œ๋‹ค.

trasient๋ฅผ ์™œ ์„ ์–ธํ•ด์•ผ ํ•˜๋Š”๊ฐ€

ํ•„์š”์—†๋‹ค๋ฉด ์ œ๊ฑฐํ•˜๋ฉด ๋œ๋‹ค. ํ•„์š” ์žˆ๋‹ค๋ฉด ์„ ์–ธํ•˜๊ณ  ์ง๋ ฌํ™” ์—ญ์ง๋ ฌํ™”๋ฅผ ํ•˜๋ฉด ๋œ๋‹ค.

ํ•˜์ง€๋งŒ ํ†ต์ œ๋ฅผ ์œ„ํ•ด์„œ readResolve ๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธํ•ด์„œ ํ†ต์ œํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์—†์œผ๋ฉด ๋„๋Œ€์ฒด ์ง๋ ฌํ™”๋ฅผ ์™œ ํ•˜๋Š”๊ฐ€?์— ๋Œ€ํ•œ ๊ณ ๋ฏผ์ด ์žˆ์—ˆ๋‹ค.

์ง๋ ฌํ™”๋ผ๋Š”๊ฒŒ ๊ฒฐ๊ตญ ํ•„๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ํ•˜๋Š” ๊ฒƒ์ธ๋ฐ ์˜ˆ๋กœ Json์ด ๋˜๊ฒ ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ํ•„๋“œ๋ฅผ ์ง๋ ฌํ™” ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์™œ ์ง๋ ฌํ™” ์—ญ์ง๋ ฌํ™”๋ฅผ ํ• ๊นŒ?

์˜ˆ๋ฅผ ํ•˜๋‚˜ ๋“ค์–ด๋ณด๋ฉด AMQP๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค. AMQP์™€ ๋‘ ์„œ๋ฒ„์˜ ํ†ต์‹ ์˜ ์ ˆ์ฐจ๋กœ ์•Œ์•„๋ณด์ž.

  1. producer ์„œ๋ฒ„๋Š” ์ง๋ ฌํ™”ํ•ด์„œ AMQP์— ๋ณด๋‚ธ๋‹ค.
  2. ์ปจ์ˆ˜๋จธ ์„œ๋ฒ„๋Š” AMQP์—์„œ pullํ•œ๋‹ค.
  3. ์ปจ์ˆ˜๋จธ ์„œ๋ฒ„๋Š” ์ด๋ฅผ ์—ญ์ง๋ ฌํ™” ํ•œ๋‹ค.

3๋ฒˆ ์ ˆ์ฐจ์—์„œ ๋งŒ์•ฝ ์ปจ์ˆ˜๋จธ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๊ณ  ๊ทธ๋ƒฅ ์ปจ์ˆจ๋งŒ ํ•˜๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ๋ผ๋ฉด

์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ readResolve ๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธํ•˜๋ฉด ์บ์‹ฑ๋œ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.

readResolve ๋ฉ”์„œ๋“œ๋Š” ์–ด๋””์— ์žˆ๋Š”๊ฐ€

์กด์žฌํ•˜๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์•„๋‹ˆ๊ณ  ๋ฆฌํ”Œ๋ ‰์…˜์„ ํ™œ์šฉํ•œ ๊ฒƒ์ด๋‹ค.

ObjectInpuStream์ด ์—ญ์ง๋ ฌํ™” ๊ด€๋ จ ํด๋ž˜์Šค๋กœ ์—ฌ๊ธฐ์„œ ๋ฆฌํ”Œ๋ ‰์…˜์„ ์‚ฌ์šฉํ•œ๋‹ค.

private Object readOrdinaryObject(boolean unshared)๋ผ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€

๋‚ด๋ถ€์ ์œผ๋กœ invokeReadResolve()๋ฅผ ํ•˜๋Š”๋ฐ ์ด๋Š” ObjectStreamClass.java์— ์กด์žฌํ•œ๋‹ค.

๋˜ํ•œ ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ObjectStreamClass.java์—์„œ๋Š” ๋ฆฌํ”Œ๋ ‰์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

readResolveMethod = getInheritableMethod(
                        cl, "readResolve", null, Object.class);
                    return null;

ํ•˜๋‚˜ ๋” ์•Œ ์ˆ˜ ์žˆ๋Š”๊ฒƒ์€ readObject๋ฉ”์„œ๋“œ์ธ๋ฐ ์ด ๋ฉ”์„œ๋“œ๊ฐ€ ๊ฒฐ๊ตญ์€ readResolve๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋œ๋‹ค.

์ฆ‰, readResolve๊ฐ€ ์žˆ๋Š”์ง€ ์ฒดํฌํ•˜๊ณ  ์žˆ์œผ๋ฉด ์‚ฌ์šฉํ•˜๊ณ  ์—†์œผ๋ฉด ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒใ…‡๋””ใ….

๐Ÿš— ์›์†Œ๊ฐ€ ํ•˜๋‚˜์ธ enum


์ฑ…์—์„œ๋Š” ๊ฐ€์žฅ ๋ฐ”๋žŒ์งํ•œ ๋ฐฉ์‹์ด๋ผ๊ณ  ํ•œ๋‹ค.

๊ฐœ์ธ์ ์œผ๋กœ ๊ฐ€์žฅ ์ด์ƒ์ ์ธ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ ๋Š” ์ƒ๊ฐํ•˜์ง€ ์•Š๋Š”๋‹ค.

์ƒ์†๋„ ์•ˆ๋˜๊ณ  ๊ตฌํ˜„๋„ ์•ˆ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋ƒฅ ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ ์Šคํ”„๋ง์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์•„๋ณด์ธ๋‹ค.

์ฆ‰, ์œ ์—ฐ์„ฑ์ด ๋–จ์–ด์ง„๋‹ค.

public enum Elvis {

  INSTANCE;

  public void method() {
    System.out.println("Elvis.method");
  }
}

๐Ÿฅฌ ์žฅ์ 

  • ์—ญ์ง๋ ฌํ™”์— ์‹ฑ๊ธ€ํ†ค์ด ๋ณด์žฅ๋œ๋‹ค.
  • ๋ฆฌํ”Œ๋ ‰์…˜ ๊ณต๊ฒฉ๋„ ๋ง‰์•„์ค€๋‹ค.

๐Ÿฅฌ ๋‹จ์ 

  • ์ƒ์†์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
๋ฐ˜์‘ํ˜•
๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค!