DIContainer
interface 생성
- 협업: 아직 구현체가 나와있지 않아도 동시 개발을 할 수 있도록
- 구현체 역할의 클래스와 구현체를 써야하는 클래스 사이의 결합력을 낮추기 위함
- 실행코드 캡슐화: 사용자가 어떤식으로 구현체가 동작하는지 알 필요가 없도록
spring-context
- org.springframwork spring-context 4.3.29
- 스프링이 관리하는 객체(bean) 관리 하기
일단은 finish
<bean>
- Defines a single (usually named) bean. A bean definition may
contain nested tags for constructor arguments, property values,
lookup methods, and replaced methods. Mixing constructor
injection and setter injection on the same bean is explicitly
supported.
Sampel-Context.xml
- CoC: Convention Over Configuration이 많이 활용됨.
- 내가 이름을 결정하지않아도 class의 simplename에 맞는 id를 제안함
예시
ISampleDAO dao = new SampleDAOImpl();
<bean id="sampleDAOImpl" class="kr.or.ddit.sample.dao.SampleDAOImpl"></bean>
생성자 만든것과 같음
SampleServiceImpl service = new SampleServiceImpl();
<bean id="sampleService" class="kr.or.ddit.sample.service.SampleServiceImpl"></bean>
ApliciationContext의 구현체의 종류와 특징
- 이것을 얼마나 잘 아느냐에 따라 개발자의실력이나뉨
Resource
https://docs.spring.io/spring-framework/docs/4.3.30.RELEASE/spring-framework-reference/htmlsingle/#resources
- 기존 java file 인터페이스를 쓸때는 무조건 절대경로가 필요했음
- 하지만 Resource 인터페이스를 사용하면 웹리소스/파일시스템리소스/클래스패스리소스에 따라 사용할 수 있음
오늘 수업 핵심
컨테이너의 사용방법
- DI 모듈 의존성을 pom.xml설정 (jar파일 가져오기: 스프링 DI 컨테이너를 사용하고 있는 모듈간의 의존성 형성)
- Spring bean metadata configuration 파일 작성
1) 컨테이너가 관리할 객체(bean) 등록
2) 등록된 bean들 간의 의존관계 형성 (의존성 주입)
- 생성자 주입(Constructor Injection) : 필수 전략 주입에 활용.
- Setter Injection : optional
- 어플리케이션의 entry point에서 DI Container의 객체를 생성
- container 가 가진 getBean으로 필요한 객체 주입 받음
- 어플리케이션 종료전 컨테이너 클로즈(그럼으로써 garbage collection이 일어날수 있도록)
컨테이너가 bean을 관리할 때 어떤 특성에 따라 관리하는지
scope
- Singleton : '특별한 설정(scope)'이 없는 한 Bean을 싱글턴으로 관리
- scope="singleton" : bean에 따라 객체1개만 생성, 미리 만들어둠
- scope="prototype" : 호출시 객체 계속 생성됨, 객체 생성시점이 뒤로 밀림 (호출시에 생성함)
- singleton으로 운영할지, prototype 으로 운영할지,
- 객체 생성 순서를 결정함
- di container를 사용하는건 객체생성권한이 개발자에 없다. 그렇지만 컨테이너가 어떤 특성에따라 bean을 관리하는지 알아야 생성순서등을 개발자가 원하는 대로 정할 수 있다.
lazy-init
- 특별한 설정(lazy-init)이 없는 한 등록된 bean의 객체가 일시에 생성됨
- 모든걸 singleton으로 관리하는게 맞을까?
- 스프링장점은 가볍다는거, 한번도 사용하지 않는 객체까지 singleton으로 관리하기위해 scope를 singleton으로 한다면 메모리에 필요없는 객체까지 로드하는것임
- 그렇다고 prototype을 쓰기엔 호출시마다 객체가 생성되기때문에 효율적이지않음
- 이럴 때 슬 수 있는게 lazy-init
- lazy-init="true" : 게을러질테야~~
- 주입직전에 객체가 생성됨
- 객체 생성시점을 뒤로 미룰 수 있음
- prototype과 비슷하지만 prototype은 새로운 객체를 생성한다는 특징이 있음
depends-on
- 객체 생성 순서를 직접 제어하기 위한 속성 (depends-on)
- depends-on 속성값으로 있는 bean을 먼저 객체생성 후 해당 객체를 만든다.
루트의 default 속성들...
- 루트에 default-lazy-init="true"가 되어도 bean자체에 lazy-init="false"면 빈속성이 이김
container는 bean의 생명주기에 따라 callback 호출 구조를 가짐
- container는 bean의 생명주기에 따라 callback 호출 구조를 가짐 (container와 함께 bean들도 라이프사이클을 갖게됨)
- init-method, destroy-method
- 의존성 주입 이후에 callback (init, destroy)가 작동함
15:57:01.700 [main] INFO o.s.~.~.~.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [kr/or/ddit/sample/conf/Container-Desc.xml]
15:57:01.755 [main] INFO o.s.~.~.GenericXmlApplicationContext - Refreshing org.springframework.context.support.GenericXmlApplicationContext@351d0846: startup date [Tue Jan 05 15:57:01 KST 2021]; root of context hierarchy
SampleDAO_Mysql 기본 생성자로 생성
SampleDAOImpl 기본 생성자로 생성
SampleServiceImpl 기본 생성자로 생성
Setter Injection 으로 주입
SampleServiceImpl 초기화
15:57:01.794 [main] INFO o.s.~.~.GenericXmlApplicationContext - Closing org.springframework.context.support.GenericXmlApplicationContext@351d0846: startup date [Tue Jan 05 15:57:01 KST 2021]; root of context hierarchy
SampleServiceImpl 소멸
인젝션 받을 수 있는 케이스 만들어보기
c 네임스페이스: 생성자 주입 간소화
property editor란?
- c 네임 스페이스 이용할때, c:double="2.5" 이런 문자열이 어떻게 더블로 들어가나? -> property editor 기능때문
- xml내에서는 모든게 문자열로 기록되나 property editor가 중간에서 converter역할을 하여적절한 타입으로 변환해줌
- 필드에서는 우리가 직접 property editor를 구현해야될때도 있음
파일 bean으로 등록하고 넣기
<bean class="java.io.File" c:pathname="d:/saveFiles"/> | c:file="file:d:/saveFiles" |
---|
file의 생성자 변수가 string이어서 그대로 string 넣어도됨 | c:file은 file객체를 요구하고있어서 리소스로더 동작시키기위해 file:을 붙여 리소스읽어야함 |
Collection-Context.xml
- c 네임스페이스 사용할 수 없기때문에 전통적 방식인 constructor-arg 사용할것
<bean id="vo1" class="kr.or.ddit.vo.CollectionDIVO">
<constructor-arg name="list">
<list>
<value>value1</value>
<value>value2</value>
</list>
</constructor-arg>
<constructor-arg name="set">
<set>
<bean class="kr.or.ddit.vo.VariousDIVO"/>
<value>value2</value>
</set>
</constructor-arg>
<constructor-arg name="map">
<map>
<entry key="key1">
<bean class="java.util.Date"></bean>
</entry>
<entry key="key2" value="value2"/>
</map>
</constructor-arg>
<constructor-arg name="props">
<props>
<prop key="prop1">propValue1</prop>
<prop key="prop2">propValue2</prop>
</props>
</constructor-arg>
<constructor-arg name="array">
<array>
<value>element1</value>
<value>element2</value>
</array>
</constructor-arg>
</bean>
p 네임스페이스: setter 주입 간소화
위의 xml과 달리 재활용가능하게만들기
Auto DI : 자동 등록하여 자동 injection받기
기타
- 제너릭타입: 실행시점에 타입체크함
- 일반적인타입: 타입체크시점이 컴파일
xml 팁
- 내가 많이 사용할 엘리먼트를 많이 갖고있는애를 기본 namespace로 두면 prefix없이 쓸수있다
properties ★
- 인메모리가 아닌 데이터를 외부에 저장해서 관리할수있음
- properties는 load()라는 메서드로 인풋스트림을 개방하여 읽어들이거나 loadFromXml()을 이용해 xml의 정보를 읽어옴
- 설정을 외부화할 수 있기때문에 읽어 들이기 위해 location이 필요
array가 util에 없는이유
- 컬렉션은 현재구현체에 대한 타입을 선택가능하지만
- 배열을 미리 bean으로 등록해서 사용하는건 불가능
- 그래도 bean으로 쓰고싶어서 factoryBean을 이용
- factoryBean: bean은 bean인데 그안에 새로운 bean을 만들어준다?
- array만 이런게아니고 calendar처럼 생성자가 protected로 묶여있는 경우에도 factoryBean을 사용
미션
- 알바 완성
- employees에서 connect by 구문, merge 연습?
- pdf ~p.28까지 정독!!★★
- terran: 객체생성은 스프링에게 맡기기
- 주제정하기 딜레이되면끝도없당