객제지향 설계
🥸 객체지향 설계를 하는 이유
코드가 점점 커지고 복잡해질 때 유지보수와 변경에 강한 “유연한 설계”를 하기 위해서
단일 책임 원칙(SRP, Single Responsibility Principle)
하나의 클래스는 하나의 책임만 가져야 한다.
🧐 Why?한 클래스가 여러 역할을 하면 수정할 때 연쇄적으로 망가질 가능성↑
🧠 비유
📦 택배기사 클래스가 “운전도 하고, 택배도 포장하고, 고객센터 전화까지 받는다?”
→ 운전 기능 하나 고치면 전화 기능이 깨짐 😱
개방 폐쇄 원칙(OCP, Open Closed Principle)
확장엔 열려 있고, 변경엔 닫혀 있어야 한다.
🧠 비유
🍕피자 가게가 “새 메뉴 추가할 때마다 요리사 클래스를 수정한다면?”
→ 요리사 터져버림 🧠💥
리스코프 치환 원칙(LSP, Liskov Substitution Principle)
부모 클래스 객체를 자식 클래스로 바꿔도 결과는 같아야 한다.
🧐 Why? 다형성을 믿고 썼는데, 자식이 부모보다 못하면 버그 발생 💣
인터페이스 분리 원칙(ISP, Interface Segregation Principle)
큰 인터페이스보다, 작은 인터페이스 여러 개가 낫다!
🧐 Why?
→ 하나의 인터페이스가 너무 많은 기능을 강요하면,
→ 쓸모없는 메서드도 구현해야 함 💢
🧠 비유
학교선생님 인터페이스
teachMath(), teachEnglish(), teachScience()
→ 미술 선생님이 왜 과학을 가르쳐야 해…? 🤯
의존 관계 원칙(Dependency Inversion Principle)
상위 모듈(서비스)이 하위 모듈(구현)에 의존하면 안된다. (구현보다는 추상(인터페이스)에 의존해야함)
🧐 Why? 구체 클래스에 의존하면, 바뀔 때마다 다 수정해야 함
ApplicationContext
Spring Contatiner : Srping Bean 관리 기능
Spring Bean이란
✔ Spring에서 관리하는 객체(인스턴스)를 “Spring Bean”이라고 함.
클래스 : 설계도
객체(Object) : 클래스로 만든 실체(인스턴스) → ⭐ 스프링 빈!
✔ 즉, Spring이 자동으로 생성하고, 관리하는 객체를 의미
컨트롤러, 서비스, 레포지토리 같은 걸 만들 때, 클래스를 만들고 → 스프링이 객체를 만들어서 관리하게 함.
그리고 그 **객체(=스프링 빈)**는 @Autowired, @Bean, @Service 등으로 다른 곳에 주입되거나 쓰이게 됨.
✔ Spring 컨테이너(Application Context)가 “Bean”을 생성하고, 필요할 때 주입(의존성 주입, DI)해 줌
Spring Bean 비유
📌 비유: “Spring은 큰 공장이고, Bean은 공장에서 만들어지는 제품”
✔ Spring 컨테이너 = 공장
✔ Spring Bean = 공장에서 만들어진 제품(객체)
✔ Spring 컨테이너가 모든 Bean을 생성하고, 관리함
BeanFactory : Spring Container의 "기본 기능"만 있는 인터페이스
ApplicationContext : BeanFactory를 확장한 "실무용 컨테이너" (BeanFactory를 상속한 자식 인터페이스)
🧊 BeanFactory (기본 기능만 있음)
• 객체 생성 (빈 생성)
• 의존성 주입 (DI)
• 지연 로딩 (lazy loading)
☀️ ApplicationContext
✨ 국제화 (i18n) 지원 : 다국어 메시지 처리(영어/한글 번역 등)
✨ 이벤트 발행 기능 : ApplicationEventPublisher
✨ AOP 지원 : 프록시 기반 기능
✨ Bean 자동 등록, 스캔 지원 : @ComponentScan, @Configuration, @Autowired 등
✨ Environment (설정 정보) 제공 : application.properties 읽기 등
✨ AnnotationConfigApplicationContext : 자바 기반 설정 지원
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(MyApp.class, args);
MyService service = context.getBean(MyService.class);
service.doSomething();
}
}
✔️ SpringApplication.run()이 반환하는 게 ApplicationContext
✔️ 그걸로 빈을 꺼낼 수도 있고, 설정 정보를 가져올 수도 있음.
서블릿 vs 스프링 빈 vs 컨트롤러(Spring Controller)
• 서블릿은 요청을 처리하는 자바 클래스 (스프링 이전 방식)
• Spring은 직접 서블릿을 안 만들고, 대신 DispatcherServlet을 사용
• 우리가 만드는 @Controller는 **스프링 빈(Spring Bean)**이고, 스프링 컨테이너가 관리함.
• → 결국, 서블릿 기반으로 동작하지만, 스프링이 다 알아서 해주니까 우리는 @Controller에만 집중하면 됨. 😄
@ControllerAdvice VS @RestControllerAdvice
공통점
전역적으로 모든 @Controller나 @RestController에서 발생하는 예외를 한 곳에서 처리해주는 역할.
@ExceptionHandler, @InitBinder, @ModelAttribute 등을 함께 사용 가능.
@ControllerAdvice
웹 MVC + 페이지 렌더링
@RestControllerAdvice
@ControllerAdvice + ResponseBody, REST API 프로젝트 (JSON 응답)
➡️ "REST" 응답용이라 HTML, 이미지, 동영상 같은 뷰나 파일 응답은 처리하지 않음.
💡그럼 “웹페이지에서 이미지나 동영상 같은 건 어떻게 처리해요?”
➡️ “정적 리소스(static resources)“나 “파일 핸들링”으로 처리
🎨 예시로 보기: 이미지/동영상 처리
1️⃣ 정적 리소스 (static/images, static/videos 등)
src
└── main
└── resources
└── static
├── images
│ └── cat.jpg
└── videos
└── intro.mp4
➡️ 그럼 클라이언트는 이렇게 요청 가능
GET http://localhost:8080/images/cat.jpg
GET http://localhost:8080/videos/intro.mp4
2️⃣ 사용자가 업로드한 파일
일반적으로 컨트롤러에서 이렇게 처리
@PostMapping("/upload")
public String handleFileUpload(@RequestParam MultipartFile file) {
// 저장하고
String savePath = "/upload/" + file.getOriginalFilename();
file.transferTo(new File(savePath));
return "업로드 완료!";
}
정리
역할 | 기능 |
REST API 오류 처리 | @RestControllerAdvice |
HTML 랜더링 / 뷰 페이지 | @ControllerAdvice + 템플릿 (jsp, thymeleaf) |
이미지, 동영상 | static 폴더 + HTTP GET 처리 |
업로드/다운로드 파일 | @RequestParam MultipartFile, ResponseEntity<Resource> |
'코딩 > sparta TIL' 카테고리의 다른 글
TIL 31 - 1 : Cookie(쿠키), Session(세션) (0) | 2025.03.31 |
---|---|
TIL 30 : DI, Validation 복습 (1) | 2025.03.31 |
TIL 28 : 이해 1도 안됨, 다시 봐야함, 그냥 강의자료 메모 🤬 (0) | 2025.03.26 |
TIL 27 : Spring 예외처리 방법 (0) | 2025.03.26 |
CH3 일정 관리 앱 만들기 (0) | 2025.03.24 |