Bean의 생명주기는 정의 읽기 → 생성 → 의존성 주입 → 초기화 → 사용 → 소멸 순으로 진행되며, Spring이 관리한다.
@Component, @Bean 등을 스캔하여 Bean 정의를 수집한다.@PostConstruct 메서드가 실행되며 초기화 작업을 수행한다.@PreDestroy 메서드가 실행되어 정리 작업을 수행한다.Profile은 환경별로 서로 다른 설정을 적용할 수 있는 Spring 기능이다.
스위치처럼 개발 환경(dev) / 운영 환경(prod) 등을 자유롭게 전환할 수 있다.
@Profile("환경이름")을 붙여 사용한다.dev, prod, test, local 같은 표준 네이밍을 많이 쓴다.[개발 환경 설정 예시]
@Configuration
@Profile("dev")
public class DevelopmentConfig {
@Bean
public DataSource dataSource() {
return DataSourceBuilder.create()
.url("jdbc:h2:mem:devdb")
.username("sa")
.password("")
.build();
}
}
[운영 환경 설정 예시]
@Configuration
@Profile("prod")
public class ProductionConfig {
@Bean
public DataSource dataSource() {
return DataSourceBuilder.create()
.url("jdbc:mysql://prod-server:3306/proddb")
.username("produser")
.password("prodpass")
.build();
}
}
[활성 프로파일 지정]
application.properties
spring.profiles.active=dev
로깅은 애플리케이션 실행 중 발생하는 이벤트/상태 정보를 기록하는 것이다.
Spring에서는 보통 SLF4J + Logback 조합이 기본이다.
| 구분 | System.out.println() | 로깅 프레임워크(Logger) |
|---|---|---|
| 역할 | 단순 콘솔 출력 | 로그를 체계적으로 기록·관리 |
| 목적 | 개발 중 임시 확인 | 운영/장애 추적/분석 |
| 출력 위치 | 콘솔 | 콘솔/파일/원격 서버 등 |
| 출력 제어 | 불가능(무조건 출력) | 로그 레벨로 출력 제어 가능 |
| 성능 | 비효율적일 수 있음(I/O 직접 호출) | 버퍼링/비동기 등으로 효율적 |
| 포맷팅 | 직접 문자열 조합 | 패턴 기반 포맷 적용 가능 |
| 실무 적합성 | 비추천 | 필수 |
System.out.println은 단순 콘솔 출력에 가깝지만, 로깅은 로그를 수집/분류/저장/검색할 수 있어 운영과 유지보수에 훨씬 유리하다.
[Logger 사용 예시]
@Controller
public class UserController {
private final UserService userService;
// 이 클래스에서 발생하는 로그를 기록할 로거
private static final Logger log = LoggerFactory.getLogger(UserController.class);
public UserController(UserService userService) {
this.userService = userService;
}
}
[로깅 레벨 설정 예시]
application.properties
logging.level.com.example=INFO
로그 레벨은 낮을수록(TRACE에 가까울수록) 더 상세한 로그를 남긴다.
| 레벨 | 설명 | 사용 시점 예시 |
|---|---|---|
| TRACE | 가장 상세한 로그 | 메서드 진입/종료, 내부 흐름 추적 |
| DEBUG | 개발용 디버깅 로그 | 로직 흐름, 변수 값 확인 |
| INFO | 일반 정보성 로그 | 서비스 시작/종료, 정상 처리 |
| WARN | 경고(복구 가능) | 설정 누락, 예상치 못한 입력 |
| ERROR | 오류(기능 실패) | 예외 발생, DB 연결 실패 |
[간단 가이드]
MVC(Model–View–Controller)는 애플리케이션을 역할별로 분리해 유지보수성과 확장성을 높이는 구조다.
레이어드 아키텍처 관점에서 보면, MVC는 주로 웹 계층(Controller/View) 중심의 패턴으로 이해하면 된다.
사용자 요청 → Controller → Service → Repository → Database
↓
View ← Controller

1) 사용자의 요청이 들어오면 DispatcherServlet이 요청을 받는다.
2) HandlerMapping이 URL에 맞는 컨트롤러(핸들러)를 찾는다.
3) HandlerAdapter가 해당 컨트롤러를 실행할 수 있도록 연결해준다.
4) 컨트롤러가 실행되고, Model에 데이터를 담고 View 이름(또는 응답)을 반환한다.
5) ViewResolver가 View 이름을 실제 View로 해석한다.
6) View가 Model 데이터를 이용해 렌더링한다.
7) 렌더링된 결과를 클라이언트에게 응답한다.

| 구분 | Forward | Redirect |
|---|---|---|
| URL 변경 | 변경 안 됨 | 변경됨 |
| 요청/응답 횟수 | 1번/1번 | 2번/2번 |
| Request 객체 | 유지됨 | 새로 생성됨 |
| 속도 | 빠름 | 상대적으로 느림 |
| 데이터 전달 | request.setAttribute() 가능 | 불가(세션/파라미터 필요) |
오늘은 여러 주제를 빠르게 훑어보는 느낌이었다. 중요한 개념이 많아서 다시 정리하고, 직접 코드로 한 번씩 써보면서 익혀야 할 것 같다. 정리만으로는 아직 “언제/어떻게” 써야 하는지 감이 잘 오지 않아서, 클론 코딩이나 간단한 실습으로 연결해보며 익숙해져야겠다.