Spring - 33.2 DI Container

갓김치·2021년 1월 5일
1

JSP+Spring

목록 보기
35/43

DIContainer

interface 생성

  • 협업: 아직 구현체가 나와있지 않아도 동시 개발을 할 수 있도록
    • 구현체 역할의 클래스와 구현체를 써야하는 클래스 사이의 결합력을 낮추기 위함
  • 실행코드 캡슐화: 사용자가 어떤식으로 구현체가 동작하는지 알 필요가 없도록

spring-context

  • org.springframwork spring-context 4.3.29

bean metadata 등록

  • 스프링이 관리하는 객체(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 인터페이스를 사용하면 웹리소스/파일시스템리소스/클래스패스리소스에 따라 사용할 수 있음



오늘 수업 핵심

컨테이너의 사용방법

  1. DI 모듈 의존성을 pom.xml설정 (jar파일 가져오기: 스프링 DI 컨테이너를 사용하고 있는 모듈간의 의존성 형성)
  2. Spring bean metadata configuration 파일 작성
    1) 컨테이너가 관리할 객체(bean) 등록
    2) 등록된 bean들 간의 의존관계 형성 (의존성 주입)
  • 생성자 주입(Constructor Injection) : 필수 전략 주입에 활용.
  • Setter Injection : optional
  1. 어플리케이션의 entry point에서 DI Container의 객체를 생성
  2. container 가 가진 getBean으로 필요한 객체 주입 받음
  3. 어플리케이션 종료전 컨테이너 클로즈(그럼으로써 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><!-- list 타입이 String이기때문 -->
				<value>value2</value>
			</list>
		</constructor-arg>
		<constructor-arg name="set">
			<set>
				<bean class="kr.or.ddit.vo.VariousDIVO"/> <!-- 기본생성자 가지고있어서 ok -->
				<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: 객체생성은 스프링에게 맡기기
  • 주제정하기 딜레이되면끝도없당
profile
갈 길이 멀다

0개의 댓글