본문으로 바로가기



구아바의 Concurrency중에 AbstractService라는게 있는데 일단 Concurrency(컨커런시)는 뭔가 계속 떠있는 것을 의미한


스프링 앱을 만들어서 서버에 올린다는 것은 올린 스프링앱이 죽지않고 서버에 계속 떠있으면서 24/7로 죽지 않고 뭔가를 계속 하도록 만들기 위해서이다.

이를테면 사용자의 api request를 받는다던지, 1초에 한번씩 db에 select를 날려서 변경을 감지한다던지 등 주로 이런 작업이다.


그럴려면 뭔가 띄워야 하는데 대체로 자바에서는 Thread를 띄운다. 그런데 이 Thread를 좀 더 관리하기 쉽게 띄울려면 구아바의 AbstractService

를 사용한다.


컨커런시(Concurrency)는 구글에 찾아보면 패러럴(Paraller)하고 비교하는게 나오는데 아래 짤을 보면 차이점을 짐작 해볼 수 있다.

출처 : https://stackoverflow.com/questions/1050222/what-is-the-difference-between-concurrency-and-parallelism




일단 AbstractService를 extends한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
import com.google.common.util.concurrent.AbstractService;
 
@Service
public class StreamEngine2 extends AbstractService {
    @Override
    protected void doStart() {
 
    }
 
    @Override
    protected void doStop() {
 
    }
}
cs


그러면 doStart()와 doStop()을 Override하게 된다.

Service의 상태가 크게 보면 3가지인데 생성 되었을 때 Init이랑 Start된 상태랑 Stop된 상태인데 doStart()를 해야 서비스가 갓 생성된 Init상태에서 Start상태로 바뀐다.

그런데 Spring을 띄울때 저 doStart()를 실행 해줄수가 없다. 왜냐하면 Bean은 Constructor(생성자)를 안타기 때문이다.

그래서 Spring에 있는게 SmartLfiecycle라는 인터페이스가 있다.

SmartLifecycle을 implement해준다.
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
import com.google.common.util.concurrent.AbstractService;
import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Service;
 
@Service
public class StreamEngine2 extends AbstractService implements SmartLifecycle {
    @Override
    protected void doStart() {
 
    }
 
    @Override
    protected void doStop() {
 
    }
 
    @Override
    public boolean isAutoStartup() {
        return false;
    }
 
    @Override
    public void stop(Runnable callback) {
 
    }
 
    @Override
    public void start() {
 
    }
 
    @Override
    public void stop() {
 
    }
 
    @Override
    public int getPhase() {
        return 0;
    }
}
cs

여기서 자세히 보아야 할 것은 isAutoStartup()이라는 메소드와 start()라는 메소드 이다.

지금은 return false;로 되어있는데 이걸 return true;로 바꾸면 start()가 실행 된다.

한번 바꿔보자.
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
import com.google.common.util.concurrent.AbstractService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Service;
 
@Service
@Slf4j
public class StreamEngine2 extends AbstractService implements SmartLifecycle {
    @Override
    protected void doStart() {
 
    }
 
    @Override
    protected void doStop() {
 
    }
 
    @Override
    public boolean isAutoStartup() {
        return true;
    }
 
    @Override
    public void stop(Runnable callback) {
 
    }
 
    @Override
    public void start() {
        log.info("hello");
    }
 
    @Override
    public void stop() {
 
    }
 
    @Override
    public int getPhase() {
        return 0;
    }
}
 
cs

위와 같이 바꾸면 로그에 c.p.data.server.disruptor.StreamEngine2  : hello 가 찍힌다.

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
import com.google.common.util.concurrent.AbstractService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Service;
 
@Service
@Slf4j
public class StreamEngine2 extends AbstractService implements SmartLifecycle {
    @Override
    protected void doStart() {
        log.info("---doStart()---");
    }
 
    @Override
    protected void doStop() {
 
    }
 
    @Override
    public boolean isAutoStartup() {
        return true;
    }
 
    @Override
    public void stop(Runnable callback) {
 
    }
 
    @Override
    public void start() {
        log.info("hello");
        this.startAsync();
    }
 
    @Override
    public void stop() {
 
    }
 
    @Override
    public int getPhase() {
        return 0;
    }
}
 
cs

그 다음에 할 것은 AbstractService를 실행 해주기 위해서 start() method에 this.startAsync();를 실행 한다.


이제 스프링 부트 앱을 띄우면 아래와 같은 결과가 나온다.


결과

hello

---doStart()--- 



end.




댓글을 달아 주세요