실습 코드 참조
moonhy7/SpringFramework: Spring Framework 실습 코드 정리 (github.com)
3.1절 스프링 IoC 시작하기
1. 스프링 설정 파일 생성
1) 스프링 설정 파일 생성
2) <bean> 설정
- class 속성 값에는 패키지 경로가 포함된 전체 클래스 경로 지정
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="tv" class="polymorphism.SamsungTV"></bean>
</beans>
2. 스프링 컨테이너 구동 및 테스트 ( _005_BoardWeb_SpringContainer )
1) TV 객체를 테스트하는 클라이언트 만들기
- 이 소스는 applicationContext.xml을 로딩해서 스프링 컨테이너 중 하나인 GenericXmlApplicationContext를 구동시킴
package polymorphism;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
public class TVUser {
public static void main(String[] args) {
//0. applicationCon에다가 bin객체 생성
//1. Spring 컨테이너를 구동한다.
AbstractApplicationContext factory = new GenericXmlApplicationContext("applicationContext.xml");
}
}
2) 실행 결과
- 콘솔창을 보면 applicationContext.xml 파일을 로딩한다는 메시지가 가장 먼저 출력됨
- 그 다음으로 GenericXmlApplicationContext 객체가 생성되어 스프링 컨테이너가 구동됐다는 메시지가 출력됨
3) SamsungTV 생성자 추가
- 구동된 컨테이너로부터 SamsungTV 객체를 얻기 위함
//생성자 만들기
public SamsungTV() {
System.out.println("====> SamsungTV 객체 생성");
}
4) getBean() 메소드를 이용하여 이름이 tv인 객체를 요청함
package polymorphism;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
public class TVUser {
public static void main(String[] args) {
//0. applicationCon에다가 bin객체 생성
//1. Spring 컨테이너를 구동한다.
AbstractApplicationContext factory = new GenericXmlApplicationContext("applicationContext.xml");
//2. Spring 컨테이너로부터 필요한 객체를 요청(Look Up)한다.
// lookup하는 순간 매핑이되서 우리가 만든 객체로 담아주게됨 (객체는 룩업하기전에 생김)
TV tv = (TV)factory.getBean("tv");
tv.powerOn();
tv.volumeUp();
tv.volumeDown();
tv.powerOff();
//3. Spring 컨테이너를 종료한다.
factory.close(); //컨테이너와 함께 객체가 삭제됨
}
}
5) 실행 화면
6) 스프링 컨테이너의 동작 순서
- 지금까지의 과정을 그림으로 표현
① TVUser 클라이언트가 스프링 설정 파일을 로딩하여 컨테이너 구동
② 스프링 설정 파일에 <bean> 등록된 SamsungTV 객체 생성
③ getBean() 메소드로 이름이 'tv'인 객체를 요청(Lookup)
④ SamsungTV 객체 반환
- SamsungTV를 LgTV로 변경할 때, applicationContext.xml 파일만 수정하면 됨
- 클라이언트 소스를 수정하지 않고도 동작하는 TV를 변경할 수 있다.
- BeanFactory 클래스 보다 유지보수가 좀 더 편해짐
3. 스프링 컨테이너의 종류
1) 스프링 컨테이너의 종류
① BeanFactory 컨테이너
- 스프링 설정 파일에 등록된 <bean> 객체를 생성하고 관리하는 기본적인 컨테이너 기능만 제공
- 지연 로딩 방식 (Lazy Loading) 사용
- <bean> 객체를 생성하는 것이 아니라 클라이언트 요청에 의해서만 <bean> 객체가 생성되는 방식임
- 일반적인 스프링 프로젝트에서는 사용할 일이 전혀 없음
② ApplicationContext 컨테이너
- BeanFactory를 상속한 컨테이너임
- <bean> 객체 관리 기능 외에도 트랜잭션 관리나 메시지 기반의 다국어 처리 등 다양한 기능 제공
- 즉시 로딩 방식 (pre-loading) 으로 동작함 (컨테이너가 구동되는 시점에 <bean> 등록된 클래스들을 객체 생성함)
- 웹 애플리케이션 개발도 지원
- 대부분의 스프링 프로젝트에서 사용됨
2) 구현 클래스 종류
- ApplicationContext의 구현 클래스
* XmlWebApplicationContext는 Spring MVC를 학습할 때 배움
3.2절 스프링 XML 설정
1. <beans> 루트 엘리먼트
- <beans> 엘리먼트 시작 태그에 네임스페이스를 비롯한 XML 스키마 관련 정보가 설정됨
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
2. <import> 엘리먼트
- 스프링 설정 파일에는 <bean> 등록 외에도 트랜잭션 관리, 예외 처리, 다국어 처리 등 다양한 설정이 필요함
- 기능별로 여러 XML 파일로 나누어 설정하여 <import> 엘리먼트를 사용하여 하나로 통합하는게 효율적임
3. <bean> 엘리먼트
- 클래스를 등록하는 엘리먼트로서 id와 class 속성을 사용 (id는 선택, class는 필수)
1) id 속성이 없어도 객체 생성 가능 테스트
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="polymorphism.SamsungTV"></bean>
</beans>
2) TVUser 프로그램 컨테이너 구동
package polymorphism;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
public class TVUser {
public static void main(String[] args) {
//1. Spring 컨테이너를 구동한다.
AbstractApplicationContext factory = new GenericXmlApplicationContext("applicationContext.xml");
}
}
3) id 속성 사용하는 이유
- 클라이언트가 객체를 요청(Lookup)할 때 이름이 반드시 지정되어야함
- <bean> 객체를 위한 이름을 지정할 때 사용하는 속성이 id임 (식별을 위해서는 컨테이너가 생성한 개체들 사이에서 유일해야 함)
4) id 식별자 작성 규칙
① 카멜표기법
② 숫자로 시작할 수 없음
③ 공백을 포함할 수 없음
④ 특수기호 사용할 수 없음
⑤ 중복이 불가함 (유일해야함)
* name 속성은 규칙이 좀 더 완화되어있음
4. <bean> 엘리먼트 속성
1) init-method 속성 ( _007_BoardWeb_SpringContainer_initMethod )
- 스프링 설정 파일에 등록된 클래스를 객체 생성할 때 디폴트 생성자를 호출함
- 객체 생성 후 멤버변수 초기화 작업이 필요할 때 init-method 속성을 사용함
<!-- init-method : 객체생성될때 사용할 메소드 매핑(초기화 메소드) -->
<bean id="tv" class="polymorphism.SamsungTV" init-method="initMethod"></bean>
- SamsungTV.java
public class SamsungTV implements TV {
//initMethod() 초기화 작업 진행
public void initMethod() {
System.out.println("객체 초기화 작업 처리...");
}
}
2) destroy-method 속성 ( _006_BoardWeb_SpringContainer_destroyMethod )
- 스프링 컨테이너가 객체를 삭제하기 직전에 호출될 임의의 메소드를 지정
- SamsungTV.java
public class SamsungTV implements TV {
//destroyMethod() 객체 삭제전 처리할 로직
public void destroyMethod() {
System.out.println("객체 삭제전 처리할 로직...");
}
}
3) init-method와 destroy-method 속성을 사용한 실행 결과
- initMethod() : 컨테이너가 구동되어 SamsungTV 객체가 생성된 직후에 호출됨
- destroyMethod() : 컨테이너가 종료되기 직전에 컨테이너는 자신이 관리하는 모든 객체를 삭제함
4) lazy-method 속성 ( _008_BoardWeb_SpringContainer_lazyInit )
- 즉시 로딩 방식은 메모리를 많이 차지하여 시스템에 부담을 줌
- 따라서 init-lazy 속성을 통해 컨테이너가 구동되는 시점이 아닌 <bean>이 사용되는 시점에 객체를 생성함
<!-- lazy-init : 객체 생성 시점 설정, 기본 값은 false(컨테이너 구동 시 바로 객체 생성), true(사용자 요청에 의해 객체 생성) -->
<bean id="tv" class="polymorphism.SamsungTV" lazy-init="true"></bean>
- true로 하면 <bean>을 미리 생성하지 않고 클라이언트가 요청하는 시점에 생성하여 메모리 관리가 효율적이 됨
5) scope 속성 ( _009_BoardWeb_SpringContainer_scope )
① 싱글톤
- bean이 스프링 컨테이너에 의해 단 하나만 생성되어 운용됨
<!-- scope : 객체를 몇개 생성할건지 설정, 기본 값 singleton(요청이 많이 와도 한 개 객체만 생성하여 사용),
prototype(요청이 온 만큼의 객체를 생성하여 리턴)
객체가 계속해서 생성되면 메모리 부하가 걸리기 때문에 singleton 사용하는 것이 바람직함 -->
<bean id="tv" class="polymorphism.SamsungTV" scope="singleton"></bean>
② 프로토타입
- <bean>이 요청될 때마다 매번 새로운 객체를 생성하여 반환
<bean id="tv" class="polymorphism.SamsungTV" scope="prototype"></bean>
댓글