Spring - 34.1 AutoDI

갓김치·2021년 1월 6일
0

JSP+Spring

목록 보기
36/43
post-thumbnail

복습

DI 컨테이너 사용 단계

설정파일의 위치에 따라 APPLICATIONTEXT의 구현체가 달라진다
설정파일의 위치에 따라 리소스로더의 종류가 달라짐
웹/파일/클래스패스 리소스인지 정적으로 정해진게 아니면 GENERIC사용 가능, 이때 PREFIX로 스마트로더를 작동시키는걸 도와줌
컨테이너한테 '이러이러한 빈' 주세요 하려면 검색조건을 설정해야함
빈 등록시에 class와 id설정 -> 빈 검색조건

컨테이너가 빈 관리시의 어떤 특성을 따라 관리하느냐

  • lazy-init, depends-on, prototype 처럼 객체생성시점을 관리하는 속성을 쓰려면 순환구조 발생에 유의하여야함

1. Singleton + Prototype

  • 특별한 설정이 없는 한 singleton
  • 이건 디자인패턴의 singleton과 다르다
  • 클래스 대상의 singleton이 아닌, bean을 대상으로 singleton
  • 객체의 생성시점을 뒤로 미뤄 주입직전에 만들어지는 prototype
  • prototype은 새로운 객체가 매번 생성됨

authMember로 생각하면

  • MemberVO의 bean을 싱글톤으로 관리한다면 세션마다 같은 멤버가 들어갈 위험이 있음
  • 이럴때 쓰는게 prototype 사용

2. lazy-init

3. depends-on

  • b를 먼저만들고 a를 만들어야한다면 depends-on으로 사용가능
  • 순환구조 발생하지 않도록 주의해야함

4. lifecycle callback (init, destroy)

Collection-Context.xml

properties

  • 인메모리가 아닌 외부에 따로 파일을 빼서 관리 가능

factoryBean

  • 실제로 등록된 객체는 FactoryBean클래스임



properties

  • dbinfo.properties
  • DBInfoVO
  • Props-Context.xml(beans,c,context,p,util, 기본네임스페이스를 util로)
  • PropertiesContextTextView

spEL을 사용하여 injection

<!-- spEL: util이용 (현재는 기본namespace여서 util: 빠짐) -->
<properties id="dbInfo" location="classpath:kr/or/ddit/various/dbinfo.properties" /><!-- prefix사용: ResourceLoader 위해-->
	
<!-- spEL에서도 사칙연산이 지원되어 dbInfo.driver-ClassName을 연산으로 판단하기때문에 연상배열으로 대체하여 쓸 수 있음 -->
<beans:bean id="vo1" class="kr.or.ddit.vo.DBInfoVO"
	c:driverClassName="#{dbInfo.driverClassName}"
	c:url="#{dbInfo['url']}"
	c:user="#{dbInfo['user']}"
	c:password="#{dbInfo['password']}"
	c:initialSize="#{dbInfo.initialSize}"
	c:maxActive="#{dbInfo.maxActive}"
	c:maxWait="#{dbInfo['maxWait']}"
>
</beans:bean>

jsp EL vs spEL

jsp ELsp EL
concat ㄴㄴ#{dbInfo.driverClassName+3}concat 지원
#{dbInfo['user']*3}* 3하면 3번출력됨
속성명이 사용됨bean의 id가 사용됨

placeholder 사용하여 property source에 편입 (injection)

<!-- property placeholder -->
<context:property-placeholder location="classpath:kr/or/ddit/various/dbinfo.properties"/>
<beans:bean id="vo2" class="kr.or.ddit.vo.DBInfoVO"
	p:driverClassName="${maindb.driverClassName}"
	p:url="${maindb.url}"
	p:user="${maindb.user}"
	p:password="${maindb.password}"
	p:initialSize="${maindb.initialSize}"
	p:maxActive="${maindb.maxActive}"
	p:maxWait="${maindb.maxWait}"
/>
  • bean 등록시는 id 필수지만 <context:property-placeholder />로 등록시엔 id 요구하지않음 -> bean이 아니라는 얘기
  • 스프링에는 property source라는 보이지 않는게 있는데 거기에 넣고 싶을때 <context:property-placeholder /> 이걸 넣는다?
  • 추가로 넣는 property이름이 기존의 property와 겹치지 않는 것이 가장 중요함
    • 우리도 property key이름에 prefix붙여주자
    • 대신 이럴땐 spEL사용시 객체로 혼동되지 않도록 연상배열 구조로 적어줘야함 #{dbInfo['maindb.driverClassName']+3}
  • placholder는 language가 아니다, 연산이 수행되지 않는다
    • p:driverClassName="${maindb.driverClassName+3}"
    • maindb.driverClassName+3 를 이름으로 인식함

저장경로 따로 관리하기

Terran

  • unit 패키지에 템플릿메서드패턴이 적용되어있음
  • FootSoldier: 템플릿가지고있음 (탬플릿클래스)
    • attack: 템플릿, walking, withWeapon: 후크
  • Medic, Marine, Firebat, Ghost
  • tool 패키지: 전략패턴
  • barrack이 팩토리객체의 역할
    • generateMarine이런애들이 객체생성담당

Auto DI

  • SampleView.java
<?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="sampleDAOImpl" class="kr.or.ddit.sample.dao.SampleDAOImpl"></bean>
	<bean id="mySqlDAO" class="kr.or.ddit.sample.dao.SampleDAO_Mysql"></bean>
	<bean id="sampleService" class="kr.or.ddit.sample.service.SampleServiceImpl">
		<property name="dao" ref="mySqlDAO" /><!-- setter에서 자바빈규약이 적용되어 dao라는 이름이 만들어짐 | 참조변수기에 ref-->
	</bean>
</beans>

Sample-Context.xml지우고 DI로 만들것임

Annotation

javax.annotation.Resource; - 권장, pojo에 더 가까움
org.springframework.beans.factory.annotation.Autowired;
inject는 엔터프라이즈형 jdk에 잇음 - 이걸 권장

java config방식

di container 분리

  • dao와 service의 xml을 분리한후 context를 계층구조로?

꿀팁

child에서 parent ctrl+space로 쓰기






기타

  • 스프링은 하위버전호환성이 좋다
    • ex) 어노테이션 없이 오토di했던 자바1.5버전 이전 스프링들도 호환이 가능함
profile
갈 길이 멀다

0개의 댓글