[RxJava] RxJava๋กœ ์‹œ์ž‘ํ•˜๋Š” Java Reactive ํ”„๋กœ๊ทธ๋ž˜๋ฐ

๋ฐ˜์‘ํ˜•

Java์—์„œ ์—ฌ๋Ÿฌ ๊ฐ€์ง€์˜ ์ผ์„ ๋™์‹œ์— ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์—๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. Java์—์„œ๋„ C++์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ select ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•˜๊ณ , Thread ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ์ด์šฉํ•ด์„œ ๋™์‹œ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ๊ฒƒ์€ ๊ทธ๋ฆฌ ํฐ ๊ณ ๋ฏผ์ด ๋  ๋ฌธ์ œ๋Š” ์•„๋‹™๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฌ๋‚˜ Java๋กœ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ Python์ด๋‚˜ Go์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์— ๋น„ํ•ด ์‚ฌ์šฉํ•˜๊ธฐ๊ฐ€ ๋ฌด์ฒ™ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ๊ทธ๋ƒฅ ๋‹จ์ˆœํ•˜๊ฒŒ Thread ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋งŒ ๊ณ ๋ คํ•œ๋‹ค๋ฉด ๊ทธ๋ฆฌ ํฐ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋œ ์ž์›์„ ๋™์‹œ์— ์‚ฌ์šฉํ•˜๋Š” ์ด์Šˆ ๋“ฑ ์ฒ˜๋ฆฌํ•ด์ค˜์•ผ ํ•  ์ผ๋“ค์ด ๊ต‰์žฅํžˆ ๋งŽ์„ ๋ฟ๋”๋Ÿฌ ์ฝ”๋“œ๋ฅผ ๊ฐ„๋žตํ•˜๊ฒŒ ์ง ๋‹คํ•˜๋”๋ผ๋„ ๋‚ด๊ฐ€ ๋งŒ๋“  ๋ฉ”์†Œ๋“œ๋‚˜ ํ•จ์ˆ˜๊ฐ€ ์Šค๋ ˆ๋“œ ์œ„์—์„œ ๋™์ž‘ํ•˜๋Š”์ง€ ๊ทธ๋ ‡์ง€ ์•Š์€์ง€๋ฅผ ํŒ๋ณ„ํ•˜๋Š” ๊ฒƒ๋„ ์‹ฌํžˆ ๊ณ ๋ คํ•ด์•ผ ๋  ๋งŒํ•œ ๋ถ€๋ถ„๋“ค์ž…๋‹ˆ๋‹ค.

 

 

 

RxJava

์ด๋Ÿฌํ•œ ๋ถˆํŽธํ•œ ์ ๋“ค์„ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“  ๊ฒƒ์ด ๋ฐ”๋กœ RxJava์ž…๋‹ˆ๋‹ค. RxJava๋Š” Netflix์—์„œ ๊ฐœ๋ฐœํ•˜์—ฌ 3.x ๋ฒ„์ „๊นŒ์ง€ ์ถœ์‹œ๋œ Java์šฉ Reactive Extension Library์ž…๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๊ธฐ ๋•Œ๋ฌธ์— Java์—์„œ ๊ณต์‹์ ์œผ๋กœ ์ง€์›๋˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ์•ˆ๋“œ๋กœ์ด๋“œ ๊ฐœ๋ฐœ์ž๋“ค์ด ๋” ์‰ฌ์šด ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€ํ‘œ์ ์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. 

 

์šฐ๋ฆฌ๋Š” ์ด๋Ÿฌํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ Reactive Programming์ด๋ผ๊ณ  ์ด์•ผ๊ธฐ ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด์— ์‚ฌ์šฉํ–ˆ๋˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ฝ”๋“œ ๋ฐฉ์‹์€ "์ด ๊ฐ์ฒด์ด์šฉํ•ด ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ, ์ด ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์—ˆ์„ ๋•Œ ๊ฒฐ๊ณผ๋ฅผ ๋งํ•ด์ค˜"๋ผ๋Š” ๋ช…๋ นํ˜• ์ด์—ˆ๋‹ค๋ฉด, ์ง€๊ธˆ์€ "ํ”„๋กœ๊ทธ๋žจ์˜ ์ƒํ™ฉ์— ๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ๋ฐ˜์‘์„ ๋ณด์—ฌ์ค˜" ๋ผ๋Š” ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ž…๋‹ˆ๋‹ค. 

 

์ด ์™ธ ๋‹ค๋ฅธ ๊ตฌํ˜„์ฒด๋กœ Akka์™€ ์ตœ๊ทผ Spring WebFlux์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” Reactor๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

RxJava๋Š” ๋Ÿฌ๋‹ ์ปค๋ธŒ๊ฐ€ ๋†’๊ณ , ๋‚ด์šฉ์ด ๋ฐฉ๋Œ€ํ•˜์—ฌ ์—ฌ๊ธฐ์„œ ๋ชจ๋“  RxJava์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ๋‹ค๋ฃจ๊ธฐ์—” ๋‹ค์†Œ ๋ฌด๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ฃผ์š” ๋‚ด์šฉ๋งŒ์„ ์ค‘์ ์ ์œผ๋กœ ๋‹ค๋ฃจ๊ณ , ๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ๋ฒ•์— ๋Œ€ํ•œ ์ด์•ผ๊ธฐ๋งŒ ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

RxJava์— ๋Œ€ํ•ด ์ข€ ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ณ  ์‹ถ๋‹ค๋ฉด, ์•„๋ž˜์˜ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด๋ณด์„ธ์š”.

 

 

ReactiveX/RxJava

RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM. - ReactiveX/RxJava

github.com

 

 

 

Start for Gradle

RxJava๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด RxJava ํ”„๋ ˆ์ž„์›Œํฌ ๋””ํŽœ๋˜์‹œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Java์—์„œ๋Š” ๋””ํŽœ๋˜์‹œ ๊ด€๋ฆฌ๋กœ mvn๊ณผ gradle ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์—ฌ๊ธฐ์„œ๋Š” Gradle์„ ๊ฐ€์ง€๊ณ  ์ง„ํ–‰ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

plugins {
    id 'java'
}

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    implementation "io.reactivex.rxjava3:rxjava:3.0.9"
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}

test {
    useJUnitPlatform()
}

๊ฐ€์žฅ ์ตœ๊ทผ ๋ฒ„์ „์€ 3.0.9์ด๊ธฐ ๋•Œ๋ฌธ์— 3.0.9๋กœ ๊ธฐ์žฌํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

 

 

Don't use "new"

RxJava์— ๋“ค์–ด๊ฐ€๊ธฐ ์ „์—, ํ•œ ๊ฐ€์ง€ ์ด์•ผ๊ธฐ๋ฅผ ํ•˜๊ณ  ๋„˜์–ด๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค. RxJava์—์„œ๋Š” new ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. RxJava์— ๋“ค์–ด ์žˆ๋Š” ํด๋ž˜์Šค๋“ค์€ ๋ชจ๋‘ Static factory ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฉฐ new ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ RxJava์— ์ž๋™ ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š” ๊ตฌํ˜„์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

/**
 * Created by Neon K.I.D on 1/4/21
 * Blog : https://blog.neonkid.xyz
 * Github : https://github.com/NEONKID
 */
public class Main {
    public static void main(String[] args) {
        Observable<String> ob = new Observable<String>() {
            @Override
            protected void subscribeActual(@NonNull Observer<? super String> observer) {
                
            }
        }
    }
}

์šฐ๋ฆฌ๊ฐ€ ๋ณดํ†ต Java๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ new ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ RxJava์—์„œ๋Š” ์œ„์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

/**
 * Created by Neon K.I.D on 1/4/21
 * Blog : https://blog.neonkid.xyz
 * Github : https://github.com/NEONKID
 */
public class Main {
    public static void main(String[] args) {
        Observable.just("Hello world").subscribe(System.out::println);
    }
}

์œ„์ฒ˜๋Ÿผ Factory ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ˜ธ์ถœํ•˜๋ฉฐ ๊ฐ€๊ธ‰์  RxJava๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” new์™€๋Š” ์ž ์‹œ ๋ฉ€์–ด์ง€๋„๋ก ํ•ฉ์‹œ๋‹ค.

 

 

 

 

How to use 

์ œ๊ฐ€ ์ฒ˜์Œ RxJava๋ฅผ ์‚ฌ์šฉํ–ˆ๋˜ ๊ฒƒ์€ 2.x ๋ฒ„์ „์ด๊ณ , ์•ˆ๋“œ๋กœ์ด๋“œ ์•ฑ์„ MVVM ํŒจํ„ด์„ ์ด์šฉํ•ด ๊ฐœ๋ฐœํ–ˆ์„ ๋•Œ์˜€์Šต๋‹ˆ๋‹ค. ๋‹น์‹œ์—๋Š” ViewModel์„ ์–ด๋–ค์‹์œผ๋กœ View์— ๋ Œ๋”๋ง ํ•  ๋•Œ๋ฅผ ์ •ํ•˜๋„๋ก ํ•  ๊ฑด์ง€๊ฐ€ ๊ฐ€์žฅ ํฐ ๊ด€๊ฑด์ด์—ˆ๋Š”๋ฐ์š”. RxJava์— ์žˆ๋Š” Observable์ด ๋„์›€์ด ๋งŽ์ด ๋˜์—ˆ๋˜ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ์„œ Observable์€ RxJava์˜ ์‹œ์ž‘๊ณผ ๋์ด๋ผ๊ณ  ํ•  ์ •๋„๋กœ ์ค‘์š”ํ•œ ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. 1.x ๋ฒ„์ „์—์„œ๋Š” Observable๊ณผ Single ํด๋ž˜์Šค๋ฅผ ์ฃผ๋ฅ˜๋กœ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด 2.x์—์„œ๋Š” Observable, Maybe, Flowable ํด๋ž˜์Šค๋ฅผ ์ƒํ™ฉ์— ๋งž๊ฒŒ ์‚ฌ์šฉ์„ ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋‚˜์•„๊ฐ”์—ˆ๋Š”๋ฐ์š”.

 

๊ทธ๋ ‡๋‹ค๋ฉด Observable์€ ๋ฌด์—‡์ผ๊นŒ์š”? ์—ฌ๊ธฐ์„œ Observe๋ผ๋Š” ๋‹จ์–ด๋ฅผ ๋ณด์‹ค ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด ๋‹จ์–ด๋Š” ๊ด€์ฐฐ์ด๋ผ๋Š” ๋œป์„ ๊ฐ€์ง€๊ณ  ์žˆ์ฃ . ๋”ฐ๋ผ์„œ ๊ด€์ฐฐํ•˜๋ ค๋Š” ๋ณ€์ˆ˜ ๋Œ€์ƒ์„ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์ด ๋Œ€์ƒ์— ๋”ฐ๋ผ์„œ ํ”„๋กœ๊ทธ๋žจ์„ ๋ฐ”๊ฟ”๊ฐ€๋Š” ํด๋ž˜์Šค๋ฅผ Observable ํด๋ž˜์Šค๋ผ ํ•ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋ ‡๋‹ค๋ฉด Observable์ด ์•„๋‹ˆ๋ผ Observed๋ผ๋Š” ๋‹จ์–ด๊ฐ€ ๋” ๋งž์ง€ ์•Š์„๊นŒ์š”? ๋งŒ์•ฝ ๊ทธ๋ ‡๋‹ค๋ฉด ์ด ํด๋ž˜์Šค๋Š” ํ•œ ๋ฒˆ ๊ด€์ฐฐํ•˜๊ณ  ๋‚œ ์ดํ›„ ๋‹ค์Œ๋ถ€ํ„ด ์•ˆ๋ผ ์ฒ˜๋Ÿผ ์ผํšŒ์šฉ์ด๊ฒ ์ง€๋งŒ Observable์€ ์ง€๊ธˆ ๋‹น์žฅ ๊ด€์ฐฐํ•˜์ง€ ์•Š์•˜๋”๋ผ๋„ ์•ž์œผ๋กœ ๊ณ„์† ๊ด€์ฐฐํ•  ๊ฒƒ์ด๋ผ๋Š” ์˜๋ฏธ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ”๋กœ ๋Œ€์ƒ์„ ๊ด€์ฐฐํ•˜๊ธฐ ๋ณด๋‹จ ์•ž์œผ๋กœ ๊ณ„์† ๋ณ€ํ™”๋ฅผ ๋ณด๋ฉด์„œ ํ”„๋กœ๊ทธ๋žจ์„ ์ด์–ด๋‚˜๊ฐˆ ๊ฒƒ ์ด๋ผ๊ณ  ๋ณด๋Š” ๊ฒŒ ๋งž์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

์ด๋Ÿฐ ์ด์•ผ๊ธฐ๋ฅผ ํ•˜๋Š” ์ด์œ ๋Š” ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ฒ˜์Œ ์ ‘ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ์ด๋Ÿฌํ•œ ๊ฐœ๋…์— ์ต์ˆ™ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ GUI ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์กฐ๊ธˆ ํ•ด๋ณด์‹  ๋ถ„๋“ค์ด๋ผ๋ฉด ์ด๋Ÿฐ ๊ฐœ๋…์ด ์ต์ˆ™ํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠน์ • ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ์ด ๋ฒ„ํŠผ์ด ํด๋ฆญ๋˜์—ˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•  ์ˆ˜ ์žˆ์ฃ . Java์—์„œ๋Š” Listener ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด ์กด์žฌํ•˜๊ณ , ์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” Thread ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ–ˆ๋Š”๋ฐ, ์‰ฝ์ง€๊ฐ€ ์•Š์ฃ .

 

RxJava์—์„œ๋Š” Thread ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ , Listener ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๋ฒˆ๊ฑฐ๋กœ์šด ์ž‘์—…์„ ๋‹ค ์•Œ์•„์„œ ํ•ด์ค๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” Observable์—์„œ ์ œ๊ณตํ•˜๋Š” ์•„๋ž˜์˜ 3๊ฐ€์ง€ ๋ฉ”์†Œ๋“œ๋งŒ์„ ๊ธฐ์–ตํ•ฉ์‹œ๋‹ค.

 

  • onNext: Observable ํด๋ž˜์Šค๊ฐ€ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐœํ–‰๋˜์—ˆ์Œ์„ ๊ฐ์ง€ํ•˜๋Š” ํ•จ์ˆ˜
  • onComplete: ๋ฐ์ดํ„ฐ ๋ฐœํ–‰์„ ๋” ์ด์ƒ ๋ฐ›์ง€ ์•Š์„ ๋•Œ ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. (์ดํ›„ onNext ํ•จ์ˆ˜๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.)
  • onError: ๋ฐ์ดํ„ฐ ๊ด€์ฐฐ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ (์ดํ›„ ์œ„ ๋‘ ๊ฐœ์˜ ํ•จ์ˆ˜๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š์œผ๋ฉฐ Observable ์‹คํ–‰ ๋˜ํ•œ ์ข…๋ฃŒ๋จ)

๊ทธ๋Ÿผ Observable ์ฝ”๋“œ๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์„œ ์จ๋ณด๋„๋ก ํ•˜์ฃ .

 

 

 

just()

/**
 * Created by Neon K.I.D on 1/4/21
 * Blog : https://blog.neonkid.xyz
 * Github : https://github.com/NEONKID
 */
public class Main {
    public static void main(String[] args) {
        Observable.just("Hello World", "Different class").subscribe(System.out::println);
    }
}

Observable ํด๋ž˜์Šค์—์„œ ์ œ๊ณต๋˜๋Š” ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜ ์ค‘์—” just ํ•จ์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด just ํ•จ์ˆ˜๋Š” ์ธ์ž๋กœ ๋„ฃ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐจ๋ก€๋กœ ๋ฐœํ–‰ํ•˜๊ณ , Observable์„ ์ƒ์„ฑํ•˜๋Š”๋ฐ์š”. ์ตœ๋Œ€ 10๊ฐœ๊นŒ์ง€ ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๊ฐ€์žฅ ์ข‹์€ ์ ์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ onNext, onComplete, onError ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์ง€ ์•Š์•„๋„ ์‰ฝ๊ฒŒ ์œ„์™€ ๊ฐ™์ด ๋™์ž‘ํ•œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. 

 

๋‘ ๊ฐ€์ง€ ๋ฐ์ดํ„ฐ๋ฅผ ์ธ์ž๋กœ ๋„ฃ๊ณ , ์‹คํ–‰ํ•œ ๊ฒฐ๊ณผ๋Š” ์œ„์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

 

 

create()

 

create ํ•จ์ˆ˜๋Š” just์™€ ๊ทธ ๊ธฐ๋Šฅ์ด ๊ฐ™์ง€๋งŒ onNext, onComplete, onError ๋“ฑ์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์ง์ ‘ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. just๋Š” ์œ„ 3๊ฐ€์ง€์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š” ๊ตฌํ˜„์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ์šฐ๋ฆฌ๋Š” subscribe ์ฒ˜๋ฆฌ๋งŒ ๋„ฃ์–ด์ฃผ๋ฉด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

create ํ•จ์ˆ˜๋Š” RxJava์— ์–ด๋Š ์ •๋„ ์ต์ˆ™ํ•ด์ง€์‹  ๋ถ„๋“ค์—๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ๋ฅผ ๊ถŒ์žฅํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. 

import io.reactivex.rxjava3.core.*;
import io.reactivex.rxjava3.disposables.Disposable;


/**
 * Created by Neon K.I.D on 1/4/21
 * Blog : https://blog.neonkid.xyz
 * Github : https://github.com/NEONKID
 */
public class Main {
    public static void main(String[] args) {
        Observable<String> observable = Observable.create(emitter -> {
            try {
                emitter.onNext("Hello");
            } catch (Exception ex) {
                emitter.onError(ex);
            }
        });

        Disposable disposable = observable.subscribe(System.out::println, Throwable::printStackTrace);
        disposable.dispose();
    }
}

Observable ํด๋ž˜์Šค๋ฅผ create ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋กœ ์ƒ์„ฑํ•˜๊ณ  ๋‚œ ๋‹ค์Œ์—๋Š” Lambda๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ์˜ ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ–ˆ์„ ๋•Œ ์–ด๋–ค ์ž‘์—…์„ ์ˆ˜ํ–‰ํ• ์ง€๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. onNext๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณ„์† ๋ฐ›๋„๋ก ํ•  ์ˆ˜๋„ ์žˆ๊ณ , ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•˜๋‹ค๋ฉด ์ด๋ฒคํŠธ๋ฅผ ์ค‘๋‹จํ•˜๋Š” onComplete๋ฅผ ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋‚ด๊ฐ€ ๋™์ž‘์‹œํ‚ค๋Š” ๋กœ์ง์„ ์ •์˜ํ–ˆ๋‹ค๋ฉด ๊ทธ๊ฒƒ์„ ์–ธ์ œ ๋™์ž‘์‹œํ‚ฌ์ง€๋ฅผ ์ •ํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์ด ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด Disposable ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. Disposable ๊ฐ์ฒด๋Š” Observable์— ์žˆ๋Š” subscribe ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ •์˜ํ•˜๊ณ , ์ด๋ฅผ ๋ฐ›์•˜์„ ๋•Œ ์ฒ˜๋ฆฌํ•  ๋ถ€๊ฐ€์ ์ธ ๋™์ž‘์„ ๊ตฌ์„ฑํ•œ ๋‹ค์Œ, dispose ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ–ˆ์„ ๋•Œ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

 

์ด์ฒ˜๋Ÿผ create๋Š” ์กฐ๊ธˆ ๋ณต์žกํ•œ๋ฐ์š”. RxJava์˜ ๋™์ž‘ ๋ฐฉ์‹์„ ์ฒœ์ฒœํžˆ ์ดํ•ดํ•œ ๋’ค์— ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

 

 

 

 

Why RxJava ?

์ด์ฒ˜๋Ÿผ RxJava ๋˜ํ•œ ๋Ÿฌ๋‹ ์ปค๋ธŒ๊ฐ€ ๋‚ฎ์ง€๋งŒ์€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  RxJava๋ฅผ ์จ์•ผํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ์š”? 

 

์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋น„๋™๊ธฐ์ ์ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ง„ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Pure Java์—์„œ ์ด๋Ÿฌํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ์ž˜ ์‚ฌ์šฉํ•  ์ค„ ์•Œ์•„์•ผ ํ•จ๊ณผ ๋™์‹œ์— ์ฝ”๋“œ๋ฅผ ๊นจ๋—ํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๋Šฅ๋ ฅ๋„ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์•„๋ž˜์˜ 3๊ฐ€์ง€ ์š”์†Œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

 

  • Thread (์Šค๋ ˆ๋“œ)
  • Listener (์ธํ„ฐํŽ˜์ด์Šค)
  • Flow (ํ๋ฆ„)

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

 

๋ฐ˜๋ฉด RxJava๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ณ„๋„๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๋“ฑ์˜ ๋ถˆํŽธํ•จ์„ ๋œ์–ด์ฃผ๊ณ , ๋ฐ์ดํ„ฐ์˜ ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๋กœ์ง์„ ๋‹จ ํ•œ ์ค„์— ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด๋ฅผ ์—ฐ๋™ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋„ ์ž˜ ๊ตฌํ˜„๋˜์–ด ์žˆ์–ด, ์ด ์ธํ„ฐํŽ˜์ด์Šค ๋˜ํ•œ ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ตฌํ˜„ํ•˜๋Š” ์ˆ˜๊ณ ๋ฅผ ๋œ์–ด์ค๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ์ฝ”๋“œ์˜ ํ๋ฆ„๋„ ์ผ์ •ํ•˜๊ฒŒ ์œ ์ง€์‹œ์ผœ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์„ ์ตœ๋Œ€ํ•œ ์‚ด๋ ค์ฃผ์ง€์š”.

 

์‹ค์ œ๋กœ Netflix๊ฐ€ RxJava๋ฅผ ๋งŒ๋“  ์ด์œ ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

  • Emberance Concurrency

    ์šฐ๋ฆฌ์˜ ํด๋ผ์ด์–ธํŠธ๋Š” ๋™์‹œ์„ฑ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๋งŽ์ด ํ•„์š”๋กœ ํ–ˆ๊ณ , ์ด๋ฅผ ์ ๊ทน์ ์œผ๋กœ ์ˆ˜์šฉํ•ด์•ผ๋งŒ ํ–ˆ๋‹ค.

  • Java Futures are Expensive to Compose

    Java์—์„œ ์ œ๊ณตํ•˜๋Š” Future๋Š” ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์— ๋งŽ์€ ๋„์›€์ด ๋˜๊ธด ํ•˜์ง€๋งŒ ์ด๋ฅผ ์กฐํ•ฉํ•˜๊ณ  ํ๋ฆ„์„ ์ œ์–ดํ•˜๋Š” ๊ฒƒ์€ ์‰ฝ์ง€ ์•Š๋‹ค.

  • Callbacks Have Their Own Problems

    ์ฝœ๋ฐฑ ์ง€์˜ฅ์€ ๋ชจ๋“  ์–ธ์–ด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์˜ ๋ฌธ์ œ์ , ๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๋„ ์ด๋ฅผ ํ•ด๊ฒฐํ•ด์•ผ ํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.

๋น„๋ก ๋‚˜์ค‘์— Java 8์—์„œ CompletableFuture๋ผ๋Š” ๋น„๋™๊ธฐ ํ๋ฆ„์„ ๋งค๋„๋Ÿฝ๊ฒŒ ์žก์•„์ฃผ๋Š” ์ข‹์€ ํด๋ž˜์Šค๊ฐ€ ๋‚˜์˜ค๊ธด ํ–ˆ์ง€๋งŒ ๋‹น์‹œ RxJava๊ฐ€ ๋‚˜์˜ฌ ๋ฌด๋ ต์—๋Š” Java 8์ด ๋‚˜์˜ค๊ธฐ ์ด์ „์ด์—ˆ๊ณ , ์ด ๋•Œ๋ฌธ์— Netflix์—์„œ๋Š” Reactive ์—ฐ์‚ฐ์ž๊นŒ์ง€ ๋งŒ๋“ค์—ˆ๋Š”๋ฐ, ๊ทธ๊ฒƒ์ด ๋ฐ”๋กœ ํ˜„์žฌ Java 8์— ์žˆ๋Š” map, stream ๋“ฑ์˜ ํ•จ์ˆ˜๋“ค์ž…๋‹ˆ๋‹ค.

 

 

 

 

 

 

๋งˆ์น˜๋ฉฐ

RxJava์— ๋Œ€ํ•ด ๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ๋ฒ•์„ ์•Œ์•„๋ดค์Šต๋‹ˆ๋‹ค. RxJava๋Š” ์ง€๋‚œ ๋‹ฌ 2.x์— ๋Œ€ํ•œ ์ง€์›์„ ๊ฑฐ์˜ ์ข…๋ฃŒํ•˜๊ณ  3.x๊นŒ์ง€ ๋„๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๋น„๋ก ์ €๋Š” 2.x์—์„œ ์™”๋‹ค๊ฐ€ ์ตœ๊ทผ์—์„œ ๋‹ค์‹œ 3.x๋ฅผ ๋ณด๋Š” ์ค‘์ด๊ธด ํ•œ๋ฐ๋„ ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ํƒ“์ธ์ง€ ํ—ท๊ฐˆ๋ฆฌ๋Š” ๋ถ€๋ถ„๋“ค์ด ๋งŽ์•˜์Šต๋‹ˆ๋‹ค.

 

์‹ค์ œ๋กœ RxJava๋ฅผ ์ฒ˜์Œํ•˜์‹œ๋Š” ๋ถ„๋“ค์€ ์–ด๋ ค์šด ๋ถ€๋ถ„์ด ๋งŽ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ƒ์†Œํ•œ ๋‹จ์–ด๋“ค, ์ถ”์ƒํ™”๋œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ฝ”๋“œ๋กœ ์ธํ•ด์„œ ์–ด๋–ค์‹์œผ๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ์ž˜ ๋ชจ๋ฅผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ํด๋ž˜์Šค์™€ Reactive ์—ฐ์‚ฐ์ž๋งŒ ์ž˜ ์ตํžˆ๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•˜๊ณ , ๊ทธ ๋‹ค์Œ๋ถ€ํ„ฐ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์„ ํ•˜๋ฉด์„œ ์ฐจ๊ทผ์ฐจ๊ทผ ๋ฐฐ์›Œ๋‚˜๊ฐ€๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

 

๋ฐ˜์‘ํ˜•
TAGS.

Tistory Comments