Spring 핵심 원리 TIL (10)
[참고 강의] 김영한님의 스프링 핵심 원리 - 기본편
✏️ 자동, 수동의 올바른 실무 운영 기준
" 편리한 자동 기능을 기본으로 사용하자 "
그러면 어떤 경우에 컴포넌트 스캔과 자동 주입을 사용하고, 어떤 경우에 설정 정보를 통해서 수동으로 빈을 등록하고, 의존관계도 수동으로 주입해야 할까?
스프링이 나오고 시간이 갈수록 점점 자동을 선호하는 추세다. 스프링은 @Component 뿐만 아니라 @Controller, @Service, @Repository 처럼 계층에 맞추어 일반적인 애플리케이션 로직을 자동으로 스캔할 수 있도록 지원한다. 최근 스프링 부트는 컴포넌트 스캔을 기본으로 사용하고, 스프링 부트의 다양한 스프링 빈들도 조건이 맞으면 자동으로 등록하도록 설계했다.
자동 빈 등록을 사용해도 OCP, DIP를 지킬 수 있다.
수동 빈 등록이 사용하면 좋을 때는?
애플리케이션은 크게 업무 로직과 기술 지원 로직으로 나눌 수 있다.
- 업무 로직 빈 : 웹을 지원하는 컨트롤러, 핵심 비즈니스 로직이 있는 서비스, 데이터 계층의 로직을 처리하는 레포지토리 등이 모두 업무 로직이다. 보통 비즈니스 요구사항을 개발할 때 추가되거나 변경된다.
- 기술 지원 빈 : 기술적인 문제나 공통 관심사(AOP)를 처리할 때 주로 사용된다. 데이터베이스 연결이나, 공통 로그 처리 처럼 업무 로직을 지원하기 위한 하부 기술이나 공통 기술들이다.
업무 로직 빈은 자동 기능을 적극 사용하는 것이 좋다. 문제가 발생했을 때 어떤 곳에서 문제가 발생했는지 명확하게 파악하기 쉽다.
기술 지원 로직은 수가 매우 적고, 광범위하게 영향을 미친다. 또한 로직이 적용 잘 되고 있는지도 파악하기 어려운 경우가 많으므로 가급적 수동 빈 등록을 사용해서 명확하게 하는 것이 좋다.
💡 빈 생명주기 콜백
✏️ 빈 생명주기 콜백
네트워크 소켓처럼 애플리케이션 시작 시점에 필요한 연결을 미리 해두고, 애플리케이션 종료 시점에 연결을 모두 종료하는 작업을 진행하려면, 객체의 초기화와 종료 작업이 필요하다.
예제 코드
package hello.core.lifecycle;
public class NetworkClient {
private String url;
public NetworkClient() {
System.out.println("생성자 호출, url = " + url);
connect();
call("초기화 연결 메시지");
}
public void setUrl(String url) {
this.url = url;
}
//서비스 시작시 호출
public void connect() {
System.out.println("connect: " + url);
}
public void call(String message) {
System.out.println("call: " + url + " message = " + message);
}
//서비스 종료시 호출
public void disconnect() {
System.out.println("close: " + url);
}
}
스프링 환경설정과 실행
public class BeanLifeCycleTest {
@Test
public void lifeCycleTest() {
ConfigurableApplicationContext ac = new AnnotationConfigApplicationContext(LifeCycleConfig.class);
NetworkClient client = ac.getBean(NetworkClient.class); ac.close(); //스프링 컨테이너를 종료, ConfigurableApplicationContext 필요
}
@Configuration
static class LifeCycleConfig {
@Bean
public NetworkClient networkClient() {
NetworkClient networkClient = new NetworkClient();
networkClient.setUrl("http://hello-spring.dev");
return networkClient;
}
}
}
실행 결과
생성자 부분을 보면 url 정보 없이 connect가 호출되는 것을 확인할 수 있다.
너무 당연한 이야기지만 객체를 생성하는 단계에는 url이 없고, 객체를 생성한 다음에 외부에서 수정자 주입을 통해서 setUrl()이 호출되어야 url이 존재하게 된다.
스프링 빈은 간단하게 다음과 같은 라이프사이클을 가진다.
객체 생성 -> 의존관계 주입
스프링은 의존관계가 주입이 완료되면 스프링 빈에게 콜백 메서드를 통해서 초기화 시점을 알려주는 다양한 기능을 제공한다. 스프링은 스프링 컨테이너가 종료되기 직전에 소멸 콜백을 주기때문에 안전하게 종료 작업을 진행할 수 있다.
스프링 빈의 이벤트 라이프사이클
스프링 컨테이너 생성 -> 스프링 빈 생성 -> 의존관계 주입 -> 초기화 콜백 -> 사용 -> 소멸 콜백 -> 스프링 종료
- 초기화 콜백: 빈이 생성되고, 빈의 의존관계 주입이 완료된 후 호출
- 소멸전 콜백 : 빈이 소멸되기 직전에 호출
스프링은 3가지 방법으로 빈 생명주기 콜백을 지원한다.
- 인터페이스
- 설정 정보에 초기화 메서드, 종료 메서드 지정
- @PostConstruct, @PreDestroy 애노테이션 지원
Author And Source
이 문제에 관하여(Spring 핵심 원리 TIL (10)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@yulhee741/Spring-핵심-원리-TIL-10저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)