-
스프링 퀵 스타트 01Spring&SpringBoot 2025. 9. 16. 14:02
DAY01
CLASS02. 프레임워크 개요
2.2.2 스프링 프레임워크 특징
1. 경량(lightweight)
- 크기 측면에서 가볍기 때문이다 (하나 이상의 JAR 파일로 이루어진 여러 개의 모듈로 구성)
- POJO 형태의 객체 (클래스를 구현하는데 특별한 규칙이 없는 단순하고 가벼운 객체) 를 관리하기 때문이다
2. 제어의 역행(IoC)
- 객체 생성을 자바 코드로 직접 처리하는 것이 아니라 컨테이너가 대신 처리
- 객체 사이의 의존관계 역시 컨테이너가 처리
- 즉, 소스 의존관계가 명시되지 않으므로 결합도가 떨어져 유지보수가 편리해진다
3. 관점지향 프로그래밍(AOP)
- 공통으로 사용하는 기능들을 외부의 독립된 클래스로 분리하고 해당 기능을 프로그램 코드에 직접 명시하지 않고 선언적으로 처리
- 응집도 높은 비즈니스 컴포넌트 만들 수 있고 유지보수가 편리해진다
4. 컨테이너
- 컨테이너는 특정 객체의 생성과 관리를 담당하며 객체 운용에 필요한 다양한 기능을 제공
- 예) sevelt Container
2.4. IoC 컨테이너
[서블릿 컨테이너 동작 순서]
1. WEB-INF/web.xml 파일을 로딩하여 구동
2. 브라우저로부터 /hello.do 요청 수신
3. hello.HelloSevlet 클래스를 찾아 객체를 생성하고 doGet() 메소드 호출
4. doGet() 메소드 실행 결과를 클라이언트 브라우저로 전송컨테이너는 자신이 관리할 클래스들이 등록된 XML 설정 파일을 로딩하여 구동한다
그리고 클라이언트의 요청이 들어오는 순간 XML 설정 파일을 참조하여 객체를 생성하고 객체의 생명주기를 관리한다
스프링 컨테이너 역시 서블릿 컨테이너와 유사하게 동작한다
2.3.3. 디자인 패턴 이용하기
결합도를 낮추기 위한 또 다른 방법으로 디자인 패턴을 이용하는 방법이 있다
TV를 교체할 때 클라이언트 소스를 수정하지 않고 TV를 교체할 수 있다면 유지보수가 더욱 편리해진다
이를 위해 Factory 패턴을 적용해야 하는데, Factory 패턴은 클라이언트에서 사용할 객체 생성을 캡슐화하여 TVUser와 TV 사이를 느슨한 결합 상태로 만들어준다
public class BeanFactory { public Object getBean(String beanName) { if (beanName.equals("samsung")) { return new SamsungTv(); } else if (beanName.equals("lg")) { return new LgTv(); } } }public class TVUser { public static void main(String[] args) { BeanFacory factory = new BeanFactory(); Tv tv = (TV)factory.getBean(args[0]); tv.powerOn(); } }CLASS03. 스프링 컨테이너 및 설정 파일
3.1. 스프링 Ioc 시작하기
3.1.1. 스프링 설정 파일 생성
# applicationContext.xml <beans> <bean id="tv" class="polymorphism.SamsungTV"/> </beans>3.1.2. 스프링 컨테이너 구동 및 테스트
public class TVUser { public static void main(String[] args) { // Spring 컨테이너 구동 AbstrctApplicationContext factory = new GenericXmlApplicationContext(applicationContext.xml); // Spring 컨테이너로부터 필요한 객체를 요청 TV tv = (TV)factory.getBean("tv"); tv.powerOn(); // Spring 컨테이너 종료 facotry.close(); } }[스프링 컨테이너 동작 순서]
1. TVUser 클라이언트가 스프링 설정 파일을 로딩하여 컨테이너 구동
2. 스프링 설정 파일에 <bean> 등록된 SamsungTV 객체 생성
3. getBean() 메서드로 이름이 'tv'인 객체를 요청
4. SamsungTV 객체 반환3.1.3 스프링 컨테이너의 종류
- BeanFactory
- 스프링 설정 파일에 등록된 객체를 생성하고 관리하는 가장 기본적인 컨테이너 기능만 제공
- 컨테이너가 구동될 때 객체를생성하는 것이 아니라 클라이언트의 요청에 의해서만 객체가 생성되는 지연 로딩 방식을 사용
- BeanFactory를 상속한 ApplicationContext
- BeanFactory가 제공하는 객체 관리 기능 외에도 트랜잭션 관리나 메세지 기반의 다국어 처리 등 다양한 기능을 지원
- 컨테이너가 구동되는 시점에서 등록된 클래스들을 객체 생성하는 즉시 로딩방식으로 동작
- GenericXmlapplicationContext : 파일 시스템이나 클래스 경로에 있는 XML 설정 파일을 로딩하여 구동하는 컨테이너
- XmlWebApplicationContext : 웹 기반의 스프링 애플리케이션을 개발할 때 사용하는 컨테이너
3.2. 스프링 XML 설정
3.2.1. <beans> 루트 엘리먼트
스프링 컨테이너는 <bean> 저장소에 해당하는 XML 설정 파일을 참조하여 <bean>의 생명주기를 관리하고 여러 가지 서비스를 제공
3.2.2. <import> 엘리먼트
<import> 태그를 이용하여 여러 스프링 설정 파일을 포함함으로써 한 파일에 작성하는 것과 같은 효과를 낼 수 있다
3.2.3. <bean> 엘리먼트
<bean> 태그는 스프링 설정 파일에 클래스를 등록할 때 사용한다
이때 id와 class 속성을 사용하는데 id는 생략 가능하지만 class 는 필수이다
- init-method : 객체를 생성한 후 멤버변수 초기화 작업이 필요할 때 사용
- destory-method : 스프링 컨테이너가 객체를 삭제하기 직전에 호출될 임의의 메소드 지정할 수 있다
<bean id="tv" class="polymorphism.SamsungTV" init-method="initMethod" /> <bean id="tv" class="polymorphism.SamsungTV" destory-method="destoryMethod" />public class SamsungTV implements TV { public void initMethod() { System.out.println("객체 초기화 작업 처리"); } ... public void destoryMethod() { System.out.println("객체 삭제 전에 처리할 로직 처리"); } }- lazy-init
ApplicationContext를 이용하여 컨테이너를 구동하면 컨테이너가 구동되는 시점에 스프링 설정 파일에 등록된 <bean>들을 생성하는 즉시 로딩 방식으로 동작한다
그런데 어떤 <bean>은 자주 사용되지 않으면서 메모리를 많이 차지하여 시스템에 부담을 준다
스프링에서는 컨테이너가 구동되는 시점이 아닌 클라이언트가 요청하는 시점에 생성할 수 있다
<bean id="tv" class="polymorphism.SamsungTV" lazy-init="ture" />- scope
scope 속성값은 기본이 싱글톤이며 이는 해당 bean이 스프링 컨테이너에 의해 단 하나만 생성되어 운용되도록 한다
scope="prototype" 로 지정할 경우 스프링 컨테이너는 해당 <bean>이 요청될 때마다 매번 새로운 객체를 생성하여 반환한다
<bean id="tv" class="polymorphism.SamsungTV" scope="singleton" /> <bean id="tv" class="polymorphism.SamsungTV" scope="prototype" />CLASS04. 의존성 주입
4.1. 의존성 관리
4.1.1. 스프링의 의존성 관리 방법
스프링 IoC는 두 가지 형태로 지원한다
- Dependency Lookup
- 컨테이너가 애플리케이션 운용에 필요한 객체를 생성하고 클라이언트는 컨테이너가 생성한 객체를 검색(Lookup)하여 사용하는 방식
- 실제 애플리케이션 개발 과정에서는 사용하지 않음
- Dependency Injection
- 객체 사이의 의존관계를 스프링 설정 파일에 등록된 정보를 바탕으로 컨테이너가 자동으로 처리해 준다
- 컨테이너가 직접 객체들 사이에 의존관계 처리하는 것을 의미
4.1.2. 의존성 관계
의존성 관계란 객체와 객체의 결합 관계
4.2 생성자 인젝션
public class SamsungTV implements TV { private SonySpeaker speaker; public SamsungTV() { System.out.println("TV 객체 생성 (1)"); } public SamsungTV(SonySpeaker speaker) { System.out.println("TV 객체 생성 (2)"); this.speaker = speaker; } ... }# apllicationContext.xml <bean id="tv" class="polymorphism.SamsungTV"> <constructor-arg ref="sony"></constructor-arg> </bean> <bean id="sony" class="polymorphism.SamsungTV"></bean>4.3 setter 인젝션 이용하기
4.3.1. setter 인젝션 기본
public class SamsungTV implements TV { private Speaker speaker; public SamsungTV() { System.out.println("TV 객체 생성 (1)"); } public void setSpeaker(Speaker speaker) { System.out.println("TV 객체 생성 (2)"); this.speaker = speaker; } ... }# apllicationContext.xml <bean id="tv" class="polymorphism.SamsungTV"> <property name="speaker" ref="sony"></property> </bean> <bean id="sony" class="polymorphism.SonySpeaker"></bean>- 스프링부트를 주로 쓰다보니까 Bean 등록하고 DI를 직접 XML에 정의하는게 참 번거롭게 느껴진다
728x90'Spring&SpringBoot' 카테고리의 다른 글
스프링 퀵 스타트 03 (0) 2025.09.18 스프링 퀵 스타트 02 (1) 2025.09.17 [스프링MVC - 2편] 로그인 처리1 - 쿠키, 세션 (0) 2025.03.04 [스프링MVC - 2편] 검증 (4) (0) 2025.03.02 [스프링MVC - 2편] 검증 (3) (1) 2025.03.02 - BeanFactory