0%

์˜ค๋Š˜์€ ํ˜„์—…์—์„œ ์—ฌ๋Ÿฌ๋ช…์ด ๋™์‹œ์— ํ”„๋กœ์ ํŠธ ์ž‘์—…์„ ํ• ๋•Œ ์œ ์šฉํ•œ PullRequest ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค ํ˜ผ์ž๋งŒ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ฒŒ ๋˜๋ฉด, ์€๊ทผ ์ด๋Ÿฐ๊ฒƒ๋“ค์— ๋Œ€ํ•œ ๊ฐœ๋…์ด ์—†์„ ์ˆ˜๋„ ์žˆ์–ด์„œ ์ƒ๊ฐ๋‚œ ๊น€์— ์ ์Šต๋‹ˆ๋‹ค.

Pull Request๋Š” ๋ญ˜๊นŒ์š”?

Pull Request ์ค„์—ฌ์„œ PR์ด๋ผ๊ณ  ํ•˜๊ณ , PR์€ ์ž์‹ ์ด ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋ฅผ Remote ์›๊ฒฉ์ง€์— ์ž๊ธฐ๊ฐ€ ์ž‘์—…ํ•œ ๋ธŒ๋žœ์น˜๋กœ push๋ฅผ ํ•˜๊ณ , ํ•ด๋‹น ์ž‘์—… ๋ธŒ๋žœ์น˜๋ฅผ mergeํ•˜๊ณ  ์‹ถ์€ ๋Œ€์ƒ์ด ๋˜๋Š” branch๋กœ PR์„ ๋‚ ๋ฆฝ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด Reviewer๋“ค์ด ์ฝ”๋“œ ๋ฆฌ๋ทฐ๋ฅผ ํ•˜๊ณ , ์ตœ์ข…์ ์œผ๋กœ Leader๊ฐ€ Confirmํ•˜๊ฒŒ ๋˜๋ฉด ๋‚ด๊ฐ€ ์ž‘์„ฑํ•œ ์†Œ์Šค๊ฐ€ mergeํ•˜๊ณ  ์‹ถ์€ ๋Œ€์ƒ์ด ๋˜๋Š” branch๋กœ merge๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

์ฃผ๋กœ Open Source๋ฅผ ํ™œ๋™ํ•˜๋Š” ๋ถ„๋“ค์ด ์ž์‹ ์ด ๊ด€์‹ฌ์žˆ์–ด ํ•˜๋Š” Project๋ฅผ Fork๋ฅผ ๋– ์„œ ์ž‘์—…ํ•˜๊ณ , PR๋ฅผ ๋‚ ๋ ค์„œ, ํ•ด๋‹น ์˜คํ”ˆ์†Œ์Šค ํ”„๋กœ์ ํŠธ์— Contributor๊ฐ€ ๋˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

๋” ์ฝ์–ด๋ณด๊ธฐ »

์ด๋ฒˆ์‹œ๊ฐ„์—๋Š” ์˜คํ”ˆ์†Œ์Šค ๋ฉ”์„ธ์ง€ ๋ธŒ๋กœ์ปค์ธ RabbitMQ๋ฅผ ๋กœ์ปฌ์— ์„ค์น˜ํ•˜๊ณ , Spring Boot ํ”„๋กœ์ ํŠธ๋ฅผ ์ด์šฉํ•ด์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋ฉ”์„ธ์ง€๋ฅผ ์ „์†กํ•˜๊ณ , Listening ํ•˜๋Š” ์ƒ˜ํ”Œ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.!!

RabbitMQ์˜ ๊ตฌ์„ฑ์š”์†Œ

๋“ค์–ด๊ฐ€๊ธฐ์— ์•ž์„œ RabbitMQ๋Š” ๋ฉ”์„ธ์ง€ํ๋กœ Advanced Message Queuing Protocol(AMQP)์˜ ๊ตฌํ˜„์ฒด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜: https://www.cloudamqp.com/img/blog/exchanges-topic-fanout-direct.png

๊ธฐ๋ณธ์ ์ธ ๋ฉ”์„ธ์ง€ํ์— ๋Œ€ํ•ด์„œ๋Š” ๋‹ค๋“ค ์•Œ๊ณ  ์žˆ์œผ๋‹ˆ๊นŒ, ๊ฐ„๋‹จํ•œ ๋‚ด์šฉ์€ ์ƒ๋žตํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. Producer๊ฐ€ ๋ฉ”์„ธ์ง€๋ฅผ ์ƒ์‚ฐํ•˜๊ณ  Message Broker์—๊ฒŒ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ด๊ณ , Consumer๋Š” Broker๋ฅผ Listening์„ ํ•˜๋ฉด์„œ ํ•ด๋‹น ๋ฉ”์„ธ์ง€๋ฅผ ์†Œ๋น„ํ•ฉ๋‹ˆ๋‹ค. RabbitMQ์—์„œ๋Š” Exchange๋ผ๋Š” ๊ฐœ๋…์ด ๋“ฑ์žฅํ•˜๋Š”๋ฐ, Producer๊ฐ€ ์–ด๋””์—๋‹ค๊ฐ€ ๋ณด๋‚ผ๋ž˜?๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. Exchange ์ข…๋ฅ˜์— ๋”ฐ๋ผ์„œ Direct, Topic, Fanout ์ด๋Ÿฐ ์‹์œผ๋กœ ์ข…๋ฅ˜๊ฐ€ ๋‚˜๋ˆ„์–ด์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆผ์ด ๋„ˆ๋ฌด ์ข‹์•„์„œ, ์„ค๋ช…์„ ๊ณ„์† ์ด์–ด๋‚˜๊ฐ€์ž๋ฉด Direct๋Š” BindingKey๋ฅผ ํ†ตํ•ด์„œ ํŠน์ • Queue์— ์ง์ ‘ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ Direct์ธ๊ฑฐ๊ฒ ์ฃ ?

Topic์€ ์ฃผ์ œ๋ฅผ ๋œปํ•˜๊ฒŒ ๋•Œ๋ฌธ์— Direct๋ณด๋‹ค๋Š” ๋ฒ”์œ„๊ฐ€ ๋„“์Šต๋‹ˆ๋‹ค. ๋‹น์—ฐํžˆ Queue๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ ๋“ฑ์žฅํ•˜๊ณ , ๊ทธ๋ ‡๋‹ค๋ฉด ๊ฐ๊ฐ Queue์— ์–ด๋–ป๊ฒŒ ํ• ๋‹นํ• ์ง€? ๐Ÿค”๊ถ๊ธˆ์ฆ์ด ์ƒ๊น๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋“ฑ์žฅํ•˜๋Š”๊ฒŒ Routing Key (Routing Pattern)์œผ๋กœ ํ์— ๋ฉ”์„ธ์ง€๋ฅผ ์Œ“๋Š” ๊ฒƒ์„ ๋งค์นญ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ Fanout์€ SpreadOut ์ฒ˜๋Ÿผ ํฉ๋ฟŒ๋ฆฌ๊ธฐ! ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋” ์ž์„ธํ•œ๊ฑด ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•˜๊ณ , ์•„๋ž˜์—์„œ Config ์„ค์ •ํ• ๋•Œ ์ถ”๊ฐ€๋กœ ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์„ค์น˜ํ•˜๊ธฐ

docker ๋กœ ์„ค์น˜ํ•˜๊ธฐ

1
$ docker run -d --hostname localhost --name my-rabbitmq  -p 5672:5672 -p 15672:15672 rabbitmq:3-management
  • localhost:15672
  • guest/guest

์˜์กด์„ฑ ์ถ”๊ฐ€

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

ํ™˜๊ฒฝ์„ค์ •

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private static final String queueName = "message-queue";
private static final String topicExchangeName = "topic-message";

@Bean
public Queue queue() {
return new Queue(queueName, false);
}

@Bean
public TopicExchange exchange() {
return new TopicExchange(topicExchangeName);
}

@Bean
public Binding binding(Queue queue, TopicExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("foo.bar.#");
}
  • Queue: ๋ฉ”์„ธ์ง€๋ฅผ ๋‹ด์„ ํ๋ฅผ ์„ค์ •
  • Exchange: ๋ฉ”์„ธ์ง€ Producer๊ฐ€ ๋ณด๋‚ด๋Š” ๊ณณ
  • Binding: ์˜ˆ์ œ์—์„œ๋Š” BindingBuilder๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์œ„์—์„œ ์„ค์ •ํ•œ Queue์™€ Exchange ๋ฅผ ๋ฐ”์ธ๋”ฉ ์‹œํ‚จ๋‹ค. with๋กœ ๋“ค์–ด๊ฐ€๋Š” ๊ฐ’์€ RoutingKey ๋กœ foo.bar.ํ•˜์œ„์˜ ๋ชจ๋“  ํ‚ค๋“ค๊ณผ ๊ด€๊ณ„๋ฅผ ๋งบ๋Š”๋‹ค.
1
2
3
4
5
6
7
8
9
10
11
@Bean
RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(messageConverter());
return rabbitTemplate;
}

@Bean
MessageConverter messageConverter() {
return new Jackson2JsonMessageConverter();
}

Jackson ๋ฉ”์„ธ์ง€ ์ปจ๋ฒ„ํ„ฐ๋ฅผ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๊ณ , RabbitTemplate๋„ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•œ๋‹ค. Spring boot๊ฐ€ ConnectionFactory๋ฅผ ์ฃผ์ž…ํ•ด์„œ ๋„ฃ์–ด์ค€๋‹ค.

๋ฉ”์„ธ์ง€ POJO

๋ฉ”์„ธ์ง€๋ฅผ ์ฃผ๊ณ  ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” CustomMessage pojo๋ฅผ ๋งŒ๋“ ๋‹ค.

1
2
3
4
@Data
public class CustomMessage {
private String text;
}

๋ฉ”์„ธ์ง€ ๋ณด๋‚ด๊ธฐ

Spring์—์„œ ApplicationRunner ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ํ”„๋กœ์ ํŠธ๊ฐ€ ์‹คํ–‰์ด๋ ๋•Œ ๋™์ž‘ํ•˜๋Š” run๋ฉ”์„œ๋“œ์—์„œ ๊ฐ„๋‹จํ•œ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private static final String topicExchange = "topic-message";
private static String routingKey = "foo.bar.baz";

@Autowired
private RabbitTemplate rabbitTemplate;

@Override
public void run(ApplicationArguments args) throws Exception {
log.info("send message.....");
IntStream.range(0,10)
.forEach(i-> {
CustomMessage message = new CustomMessage();
message.setText("hello message : " + i);
log.info("send message :{}", message);
rabbitTemplate.convertAndSend(topicExchange, routingKey, message);
});
}

rabbitTemplate์œผ๋กœ message ๊ฐ์ฒด๋ฅผ json์œผ๋กœ ๋ณ€ํ™˜ํ•ด์„œ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

๋ฉ”์„ธ์ง€ ๋ฐ›๊ธฐ

1
2
3
4
@RabbitListener(queues = "message-queue")
public void receiveMessage(Message message) {
log.info("receive message :{}", message);
}

Listener๋Š” ๋น„๊ต์  ๊ฐ„๋‹จํ•˜๊ฒŒ ์•ž์—์„œ ๋ณด๋ƒˆ๋˜ @RabbitListner ์–ด๋…ธํ…Œ์ด์…˜์˜ queues ์†์„ฑ์„ ์„ค์ •ํ•˜๋ฉด ํ•ด๋‹น ํ์— ์ ์žฌ๋œ ๋ฉ”์„ธ์ง€๋ฅผ ์ฝ์–ด๋“ค์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์Šคํฌ๋ฆฐ์ƒท 2020-11-25 ์˜ค์ „ 9 20 05

๋งˆ์น˜๋ฉฐ

์ด๋ฒˆ์‹œ๊ฐ„์—๋Š” ์•„์ฃผ ๊ฐ„๋‹จํ•œ RabbitMQ๋ฅผ ์„ค์น˜ํ•˜๊ณ , SpringBoot ํ”„๋กœ์ ํŠธ๋ž‘ ์—ฐ๋™ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ดค์Šต๋‹ˆ๋‹ค.๊ธฐ๋ณธ์ ์ธ TopicExchnage ์™ธ์—๋„ ๋‹ค๋ฅธ Exchange๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•, Batch๋กœ ๋ฉ”์„ธ์ง€๋ฅผ ์ „์†กํ•˜๊ณ  Listenํ•˜๋Š” ๋ฐฉ๋ฒ•, ํ ๋„ค์ด๋ฐ์ „๋žต, ํด๋Ÿฌ์Šคํ„ฐ ๊ตฌ์„ฑ, fail-over ๋“ฑ๋“ฑ.. ๋งŽ์€ ๊ฒƒ๋“ค์„ ์‹œ๋„ํ•ด ๋ณผ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ์ ํŠธ๋ผ๊ณ  ์ƒ๊ฐ๋ฉ๋‹ˆ๋‹ค.

AWS ๋žŒ๋‹ค ์„œ๋น„์Šค๋Š” serverless๋กœ ์„œ๋ฒ„์— ๋Œ€ํ•œ ์šด์˜์„ AWS Lambda ์„œ๋น„์Šค๋กœ ์ œ๊ณตํ•œ๋‹ค. ๊ธฐ์กด์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ๋‹ค๋ฅธ ๋ฐฉ์‹์€ ์ƒํƒœ๊ฐ’์„ ์œ ์ง€ํ•˜์ง€ ๋ชปํ•˜๋Š” stateless์ด๊ณ , ๋งค๋ฒˆ lambda function์ด ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์ด ๋น„๋™๊ธฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋Ÿฐ๊ฒƒ๋“ค์„ ์ƒ๊ฐํ•˜๋ฉด์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ•ด์•ผ ํ•œ๋‹ค.~

๋” ์ฝ์–ด๋ณด๊ธฐ »

Spring Cloud feign์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž. feign์€ ~์ฒดํ•˜๋‹ค ๋ผ๋Š” ๋œป์œผ๋กœ, netflix์—์„œ ๊ฐœ๋ฐœํ•œ ์ผ์ข…์˜ restTemplate์™€ ๋น„์Šทํ•˜๋‹ค๊ณ  ๋ณธ๋‹ค.
๋น„๊ต์  ์‰ฌ์šด ์„ค์ •์œผ๋กœ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์—๋งŒ ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

๋” ์ฝ์–ด๋ณด๊ธฐ »

์ฃผ๊ธฐ์ ์œผ๋กœ ์—…๋ฐ์ดํŠธ ์˜ˆ์ •!

์˜ˆ์ „์— ํฌ๋งทํ•˜๊ณ  ๋งฅ ๋‹ค์‹œ ์„ค์น˜ํ•˜๋ฉด์„œ ์˜ฌ๋ ธ๋˜ ๋‚ด์šฉ์ธ๋ฐ, ์ƒˆ๋กญ๊ฒŒ ์ •๋ฆฌํ•ด์„œ ๋‹ค์‹œ ๊ณต์œ  ํ•ฉ๋‹ˆ๋‹ค. ์ œ๊ฐ€ ์ฃผ๋กœ ๊ฐœ๋ฐœํ• ๋•Œ ์“ฐ๋Š” ํ”„๋กœ๊ทธ๋žจ ๋ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ๋“ค์„ ๋ชจ์•„๋ดค์Šต๋‹ˆ๋‹ค.

๋” ์ฝ์–ด๋ณด๊ธฐ »

MSA ์‹œ์Šคํ…œ ํŠน์„ฑ์ƒ ์—ฌ๋Ÿฌ๊ฐœ์˜ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ๋„์šฐ๋‹ค ๋ณด๋ฉด, configuration ์ •๋ณด๊ฐ€ ์ด๊ณณ์ €๊ณณ์— ํฉ์–ด์ ธ ์žˆ๋‹ค๋ณด๋‹ˆ๊นŒ, ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ํ•œ๋ˆˆ์— ํŒŒ์•…ํ•˜๊ธฐ๊ฐ€ ํž˜๋“ค๋‹ค.
๊ทธ๋ž˜์„œ spring cloud config ๋ผ๋Š” ํ”„๋กœ์ ํŠธ๊ฐ€ ๋‚˜์™”๋‹ค.

๋” ์ฝ์–ด๋ณด๊ธฐ »

๋“ค์–ด๊ฐ€๋ฉฐ

์ด์ „ ์‹œ๊ฐ„์—๋Š” ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘์˜ ๊ธฐ์ดˆ ๋‹ค๋Œ€์ผ ๋งคํ•‘ํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ์—ฐ๊ด€๊ด€๊ณ„ ์ฃผ์ธ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์•˜๋‹ค. ์ด๋ฒˆ์—๋Š” ์–‘๋ฐฉํ–ฅ ๋งคํ•‘์„ ํ• ๋•Œ, ๊ฐ์ฒด ๊ด€์ ์—์„œ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ• ์ง€?๋ฅผ ๊ณ ๋ฏผํ•ด๋ณด์ž.

๋” ์ฝ์–ด๋ณด๊ธฐ »

Future ์ธํ„ฐํŽ˜์ด์Šค๋Š” java5๋ถ€ํ„ฐ java.util.concurrency ํŒจํ‚ค์ง€์—์„œ ๋น„๋™๊ธฐ์˜ ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฐ›๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋น„๋™๊ธฐ์˜ ๊ฒฐ๊ณผ๊ฐ’์„ ์กฐํ•ฉํ•˜๊ฑฐ๋‚˜, error๋ฅผ ํ•ธ๋“ค๋งํ•  ์ˆ˜๊ฐ€ ์—†์—ˆ๋‹ค.

์ž๋ฐ”8๋ถ€ํ„ฐ CompletableFuture ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์†Œ๊ฐœ๋˜์—ˆ๊ณ , Future ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•จ๊ณผ ๋™์‹œ์— CompletionStage ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค. CompletionStage๋Š” ๋น„๋™๊ธฐ ์—ฐ์‚ฐ Step์„ ์ œ๊ณตํ•ด์„œ ๊ณ„์† ์ฒด์ด๋‹ ํ˜•ํƒœ๋กœ ์กฐํ•ฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

๋” ์ฝ์–ด๋ณด๊ธฐ »

Java์—์„œ๋Š” ๋ฌธ์ž์—ด์„ ๋‹ค๋ฃจ๋Š”๋ฐ String, StringBuffer,StringBuilder๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฐ๊ฐ ์–ด๋–ค ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

String Pool?

1
2
3
4
5
6
7
8
9
public static void main(String[] args){
String s1 = "Cat";
String s2 = "Cat";
String s3 = new String("Cat");

System.out.println(s1==s2); // true
System.out.println(s1==s3); // false

}

์ฒซ๋ฒˆ์งธ๋Š” String Pool์— ์กด์žฌํ•˜๊ฒŒ ๋˜๊ณ , ๋‘๋ฒˆ์งธ new ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด String pool์— ์˜ฌ๋ผ๊ฐ€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋™์ผ์„ฑ(identity) ๋น„๊ต์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

Journal Dev ๋ฐœ์ทŒ

์™œ String Pool์„ ์‚ฌ์šฉํ• ๊นŒ? Connection Pool, Thread Pool, ๋ชจ๋“  ํ’€์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ๋‹น์—ฐํžˆ ์žฌํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ์ž…๋‹ˆ๋‹ค.

String ํด๋ž˜์Šค์˜ intern๋ฉ”์„œ๋“œ๋Š”?

if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.

๋งŒ์•ฝ์— String pool์— ์กด์žฌํ•˜๋ฉด pool์—์„œ ๋ฐ”๋กœ return ํ•˜๊ณ , String pool์— ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด pool์— ์ถ”๊ฐ€ํ•˜๊ณ , String ๊ฐ์ฒด์˜ ์ฐธ์กฐ๊ฐ’์„ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์œ„์˜ ์˜ˆ์ œ์—์„œ s1 == s3.intern() ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•˜๊ฒŒ๋˜๋ฉด true๊ฐ’์„ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค.

String์€ Immutable ๋ถˆ๋ณ€ ๊ฐ์ฒด ์ž…๋‹ˆ๋‹ค.

๋ถˆ๋ณ€์ด๋ผ๋Š” ๋ง์€, ๋งค๋ฒˆ ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“ ๋‹ค. ์ฆ‰, ํ•œ๋ฒˆ ๋งŒ๋“ค์–ด์ง„ ๊ฐ์ฒด๋Š” ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋‹ค ๋ผ๋Š” ๋œป์ž…๋‹ˆ๋‹ค. ์ฆ‰ concat์ด๋‚˜ + ์˜คํผ๋ ˆ์ด์…˜์„ ํ†ตํ•ด์„œ ๋ฌธ์ž์—ด์„ ํ•ฉ์น˜๊ฑฐ๋‚˜ ๊ฐ€๊ณตํ• ๋•Œ ๋งˆ๋‹ค ๊ทธ๋•Œ ๋งˆ๋‹ค ๋งค๋ฒˆ ์ƒˆ๋กœ์šด String ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ํ• ๋‹นํ•˜๊ณ , ์˜ˆ์ „์— ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” String์€ GC์— ์˜ํ•ด์„œ ์ˆ˜๊ฑฐ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ์— ์—„์ฒญ๋‚œ ์ˆ˜์˜ ๋ฌธ์ž์—ด์„ ์กฐ์ž‘ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณด์‹ญ์‹œ์š”. ์‚ฌ์šฉํ•˜์ง€๋„ ์•Š๋Š” ํž™ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ๋“ค์„ ์ฐจ์ง€ํ•˜๊ฒŒ ๋˜๊ณ (๋‚˜์ค‘์— GC์— ์˜ํ•ด ์ˆ˜๊ฑฐํ•˜๋”๋ผ๋„) ๋ฉ”๋ชจ๋ฆฌ Leak์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ž๋ฐ”์—์„œ๋Š” StringBuffer, StringBuilder๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

StringBuilder, StringBuffer ๋Š” mutable ํ•ฉ๋‹ˆ๋‹ค.

StringBuffer, StringBuilder๋Š” String๊ณผ ๋‹ค๋ฅด๊ฒŒ mutable ํ•œ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. append(), insert(), delete() and substring() ์ด๋Ÿฐ ๋ฉ”์„œ๋“œ๋“ค์„ ํ†ตํ•ด์„œ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ƒˆ๋กญ๊ฒŒ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ, ๊ฐ€๋ณ€์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋Š˜๋ ค๋‚˜๊ฐ‘๋‹ˆ๋‹ค.

StringBuffer vs StringBuilder์˜ ์ฐจ์ด๋Š” ๋ฌด์—‡์ผ๊นŒ์š” ?

StringBuffer๋Š” ๋ชจ๋“  public ๋ฉ”์„œ๋“œ์— syncronized ํ‚ค์›Œ๋“œ๊ฐ€ ๋ถ™์–ด์žˆ์Šต๋‹ˆ๋‹ค. ๋ง์ธ ์ฆ‰์Šจ, Thread-safeํ•˜๋‹ค๋Š” ๋ง์ž…๋‹ˆ๋‹ค. ๋™์‹œ์— Thread-safeํ•˜๋‹ค๋Š” ๋ง์€ ์ž์›์„ ์„ ์ ํ• ๋•Œ Lock๋ฅผ ๊ฑธ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋งŒํผ์˜ ์„ฑ๋Šฅ ํšจ์œจ์ด ๋งค์šฐ ์•ˆ ์ข‹๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ 1.4๋•Œ๊นŒ์ง€๋Š” StringBuffer๋ฅผ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ, ๊ทธ ์ดํ›„ ๋ฒ„์ „์—๋Š” StringBuilder๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. StringBuilder๋Š” ๊ทธ์— ๋ฐ˜ํ•ด ๋‹น์—ฐํžˆ ์„ฑ๋Šฅ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์ •๋ฆฌ

  • String์€ imutableํด๋ž˜์Šค StringBuffer, StringBuilder๋Š” mutableํด๋ž˜์Šค
  • StringBuffer๋Š” thread-safe ํ•˜์ง€๋งŒ ์„ฑ๋Šฅ์ด ๋Š๋ฆฌ๋‹ค.
  • StringBuilder๋Š” thread-safe ํ•˜์ง€ ์•Š์ง€๋งŒ, ์„ฑ๋Šฅ์€ ๋น ๋ฅด๋‹ค.
  • ๊ทธ๋ž˜์„œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์ด ์•„๋‹Œ, ๋ฌธ์ž์—ด ์—ฐ์‚ฐ์ด ๋งŽ์€ ๊ฒฝ์šฐ์—๋Š” โ†’ StringBuilder๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • ๋ฌธ์ž์—ด ์—ฐ์‚ฐ์ด ๋งŽ์ด ์—†๊ณ , ๋‹จ์ˆœํžˆ ๊ฐ’๋“ค๋งŒ์„ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒฝ์šฐ์—๋Š” โ†’ String Pool์—์„œ ๊ฐ€์ ธ์˜ค๋ฏ€๋กœ String ์‚ฌ์šฉํ•œ๋‹ค.