에러 탈출 일지
IoC 컨테이너 본문
< IoC 컨테이너 >
예제: 프로젝트 _04_SpringFramework_SpringContainer
1. factory 디자인 패턴: 필용한 모듈(객체 등)을 미리 factory 안에 모두 생성한 뒤 알맞은 모듈을 꺼내 사용하는 방식
2. 스프링 컨테이너에는 factory 디자인 패턴이 적용되어 있다.
- <bean>으로 등록된 객체들을 스프링 컨테이너가 구동될 때 생성한다.
- @Component(@Controller, @Service, @Repository 등)을 가지는 객체들도 스프링 컨테이너가 구동될 때 생성한다
- 이렇게 생성된 객체들을 factory안에 가지고 있다가 알맞은 객체 호출이 있을 때 알아서 의존성 주입을 실행한다
3. IoC (Inverse of Control: 제어의 역전)
- 기존에 개발자들이 하던 객체 생성 및 의존성 주입을 스프링 컨테이너에서 알아서 처리한다.
public class TvUser {
public static void main(String[] args) {
// TV인터페이스를 이용하여 결합도와 의존성을 낮춤
TV tv;
tv = new SamsungTV();
tv.turnOn();
tv.volumeUp();
tv.volumeDown();
tv.turnOff();
tv = new LgTV();
tv.turnOn();
tv.volumeUp();
tv.volumeDown();
tv.turnOff();
}
}
- 티비를 변경하고 싶을 때 인스턴스화 하는 부분의 소스코드를 지속적으로 변경해야 한다.
- 스프링에선 설정파일(스프링 컨테이너)에 미리 객체를 생성한 뒤 DI(의존성 주입)해주는 것을 지원한다. → 팩토리 패턴
bean 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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<!-- Root Context(프로젝트 별로 파일 이름이 다를 수 있음): 부모 스프링 컨테이너를 만드는 설정 파일 -->
<!-- bean 객체 생성 -->
<!-- 컨테이너가 구동되면서 자동으로 생성 -->
<!-- 어떤 id로 어떤 객체를 생성할건지 -->
<bean id="sTv" class="com.ezen.spring.polymorphism.SamsungTV"/>
<bean id="lTv" class="com.ezen.spring.polymorphism.LgTV"/>
</beans>
public class TvUser {
public static void main(String[] args) {
// 1. 스프링 컨테이너 구동
AbstractApplicationContext factory =
new GenericXmlApplicationContext("root-context.xml");
// 2. DL과 DI
// DL(Dependency Lookup): sTv라는 id를 가진 bean객체를 찾음
// DI(Dependency Injection): DL에서 찾은 bean객체를 tv 의존성에 주입
TV tv = (TV)factory.getBean("sTv");
tv.turnOn();
tv.volumeUp();
tv.volumeDown();
tv.turnOff();
// 3. 스프링 컨테이너 종료
factory.close();
}
}
TV tv = (TV)factory.getBean("sTv"); 에서 아이디만 바꿔주면 됨 (코드가 더욱 간단해짐)
< 스프링 XML 파일 설정 >
1. \<beans\> 루트 엘리먼트
- 원격 저장소에 있는 설정 파일을 참조하여 \<beans\>의 생명주기 관리
- \<beans\>외의 다른 엘리먼트 사용가능 하도록 만듦. 또한 다른 여러가지 서비스를 제공
- 스프링 설정 파일은 항상 루트 엘리먼트로 \<beans\>를 사용해야 한다.
- namespce 탭을 이용하면 사용할 엘리먼트의 설정 파일 참조가 쉬워진다.
2. \<import\> 엘리먼트
- 스프링 설정 파일에서 사용할 외부 파일을 참조할 때 사용
- 문제발생: 모든 설정들이 하나의 스프링 설정 파일에 작성되면 스프링 설정 파일의 길이기 길어지고 수정도 쉽지 않음.
대표적으로 DataBase 설정이나 Transaction 설정 등을 외부 파일로 분리하여 참조한다. (참조 파일 resource 속성으로 지정)
3. \<bean>\ 엘리먼트
- 스프링 설정 파일에 클래스 등록하고, 그 클래스에 대한 객체가 자동적으로 생성되야 할 때 \<bean\>엘리먼트 사용.
- \<bean\> 엘리먼트로 등록된 클래스는 스프링 컨테이너 구동시 자동으로 객체 생성
4. \<bean\> 엘리먼트의 속성
(1) init-method
- init-method 속성을 사용하면 객체가 생성될 때 호출할 메소드를 지정할 수 있다.
- \<bean\> 엘리먼트로 생성되는 객체는 항상 기본 생성자를 호출하기 때문에 멤버변수의 초기화가 필요한 객체에는 init-method 속성을 초기화 메소드를 등록해야 한다
- \<bean id="sTv" class="....SamsungTV" init-method="메소드명"\>
- 예제 프로젝트: _005_SpringFramework_BeanProperties
(2) destory-method
- 스프링 컨테이너가 객체를 삭제하기 전에 객체에서 처리할 동작을 메소드로 만들어서 지정한다.
- \<bean id="sTv" class="....SamsungTV" destroy-method="메소드명"\>
- 예제 프로젝트: _005_SpringFramework_BeanProperties
(3) lazy-init
- 객체 생성 시점을 지정. true나 false로 지정 가능하며 기본값 false로 설정되어 스프링 구동될 때 객체를 생성.
- true로 설정했을 경우 사용자가 그 객체를 요청했을 때 객체를 생성
- \<bean id="sTv" class="....SamsungTV" lay=zy-init="true or false"\>
- 예제 프로젝트: _005_SpringFramework_BeanProperties
(4) scope
- 객체 생성 방식을 지정. singleton을 지정할 수 있는데 singleton으로 지정하면 하나의 객체만 생성하고, 이 객체를 공유해서 사용
- 지정하지 않을시 새로운 객체를 계속해서 생성
- 스프링은 기본값이 singleton으로 하나의 객체만 생성
- prototype 지정시 여러 개 객체 생성
- scope="prototype"일 때 생성되는 객체들은 singletonBean이 아닌 disposableBean으로 생성되기 때문에 삭제할 수가 없다.
- disposableBean의 특성은 다른 지원에 대한 참조를 가질 수 없고 DB연결이나 Session객체 같이 참조 후에 바로 가비지 컬렉터에 의해 삭제됨.
- disposableBean을 스프링에서 삭제시키려면 singletonBean 전처리기를 생성하여 처리해야 한다.
- 출처: https://bluebreeze0812.github.io/learn/2019/10/17/Spring-Destroy-Prototype-Beans/
- \<bean id="sTv" class="...SamsumgTV" scope="singleton or prototype">
- 예제 프로젝트: _005_SpringFramework_BeanProperties
< 의존성 주입 >
1. IoC의 두 가지 방식
- DL(Dependency Lookup)과 DI(Dependency Injection)은 스프링에서 제공하는 IoC의 두 가지 방식이다.
- DL은 알맞은 의존성을 검색하는 기능
- DI은 의존성을 주입하는 기능
- DL과 DI가 항상 함께 실행되지는 않는다. (DI가 좀 더 많은 방법 가지고 있음)
- DI 방식의 종류: setter injection(세터함수를 이용한 의존성 주입), contructor injection(생성자함수를 이용한 의존성 주입)
- 예제 프로젝트: _006_SpringFramework_DI
2. 생성자 함수를 이용한 DI
- 생성자 함수를 통한 의존성 주입은 스프링 설정 파일에 constructor-arg 엘리먼트를 이용해서 멤버객체에 들어갈 객체를 참조하여 기본 생성자가 아닌 다른 생성자를 호출하므로써 이뤄진다.
-예제 프로젝트: _007_SpringFramework_DI_Constructor
- 다중 매개변수인 생성자 함수일 경우 constructor-arg 엘리먼트를 여러 개 사용하여 매핑한다. 객체는 ref속성으로 참조 일반적인 값이 들어갈 경우 value속성으로 설정.
- public SamsungTV(SonySpeaker speaker, int price) {
}
<bean> <constructor-arg ref="sony"></constructor-arg> <constructor-arg value="100000"></constructor-arg> </bean>
- 여러개의 매개변수가 존재하는 생성자 함수 호출할 때는 constructor-arg 엘리먼트의 index속성으로 몇 번째 매개변수인지 명시할 수 있다.
<bean>
<constructor-arg index="0" ref="sony"></constructor-arg>
<constructor-arg index="1" value="100000"></constructor-arg>
</bean>
- 예제 프로젝트: _007_SpringFramework_DI_Constructor
- 예제 프로젝트: _008_SpringFramework_DI_Constructor_Interface
3.세터 함수를 이용한 DI
- 의존성을 주입할 객체에 해당 멤버변수(속성)에 해당하는 세터함수를 미리 작성한다.
- <property> 엘리먼트를 사용하여 해당 세터함수를 호출 <bean> <property name="세터함수의 이름" ref or value="멤버변수에 의존성 주입할 값이나 객체"></property> </bean>
- setSpeaker()라는 세터함수가 존재할 때 세터함수의 이름은 set을 제외한 Speaker가 세터함수의 이름이 되고 첫 번째 단어의 첫 글자는 소문자로 지정돼야 하기때문에 speaker가 최종적인 세터함수의 이름이 됩니다.(카멜케이스 적용) setNameList() -> nameList
- 예제 프로젝트: _009_SpringFramework_DI_Setter
- p namespace를 사용하여 세터함수를 효율적으로 호출하기 <bean p:멤버변수명(멤버변수가 객체일 경우)-ref="의존성 주입될 객체" p:멤버변수명(멤버변수가 일반 데이터타입)="넣어줄 값" > </bean>
- 예제 프로젝트: _009_SpringFramework_DI_Setter
4. 어노테이션을 이용한 의존성 주입
- context namespace를 추가하영 사용한다.
- context namespace에는 component-scan이라는 기능이 있다. 속성 값으로 패키지를 지정해서 지정된 패키지에 있는 클래스들 안에서 @Component가 선언된 클래스들만 찾아서 자동으로 객체로 만듦.
- @Component는 최상위 어노테이션이다. @Controller, @Service, @Repository 등은 @Component를 상속받아 구현됨. 따라서 component-scan 위 나열한 어노테이션들도 함께 걸린다.
- 스프링 설정 파일 <context:component-scan base-package="컴포넌트 스캔할 패키지명">
- 클래스 선언부 위줄에 어노테이션을 달아준다. @Component public class SamsungTV
- component-scan으로 생성될 객체에 id를 지정하는 방식은 @Component("id값")
- 예제 프로젝트: _010_SpringFramework_DI_Annotation
'개발 > SpringFramework' 카테고리의 다른 글
JSTL(Jsp Standard Tag Library) (0) | 2022.11.17 |
---|---|
트랜잭션 (0) | 2022.11.16 |
AOP (0) | 2022.11.15 |
비즈니스 컴포넌트(Service, ServiceImpl, DAO) (0) | 2022.11.14 |
Spring Framework (0) | 2022.11.11 |