개발자 미니민의 개발스터디

[spring] 의존성 주입 - 생성자, setter, 프로퍼티 파일

by mini_min
[spring] 의존성 주입 - 생성자, setter, 프로퍼티 파일

✔️ 생성자로 의존성 주입

: <constructor-arg ref="userService2"/>

: 컨테이너가 기본 생성자가 아닌, 매개변수가 존재하는 생성자를 호출할 수 있도록 설정한다.

: 생성자를 통해 의존관계가 있는 Bean 을 주입하려면 해당 태그의 <ref> 태그 사용

ref : 인자로 전달될 데이터가 <bean> 으로 등록된 다른 객체인 경우 ref 를 사용하여 해당 객체의 아이디나 이름을 참조한다.

(index, name, type 으로 순서대로 매개변수에 전달 가능)

<bean id="user" class="com.user1.User">
    <constructor-arg ref="userService2"/>
</bean>

 

 

: <constructor-arg ref="userService2"/>

:인자가 있는 생성자를 이용하여 빈을 정의

: c 네임스페이스를 이용하여 생성자에 값 설정이 가능하다.

✨ init 과 destroy 메소드도 호출 가능

<!-- 인자가 있는 생성자를 이용하여 빈 정의 -->
<!-- c 네임스페이스를 이용하여 생성자에 값 설정 -->
<bean id="userService" class="com.user2.UserServiceImpl2"
    c:name="네임스페이스" c:tel="010-1111-2222" c:age="20"/>

<!-- c 네임스페이스를 이용한 의존성 주입 -->
<bean id="user" class="com.user2.User"
    c:userService-ref="userService"
    init-method="init"
    destroy-method="destroy"
/>
package com.user2;

public class User {
	private UserService userService;
	
	
	public User(UserService userService) {
		this.userService = userService;
	}
	
	public void init() {
		System.out.println("초기화는 여기서... ");
	}
	
	
	public void write() {
		String s = userService.message();
		
		System.out.println("--생성자를 이용한 의존성 주입 : c 네임스페이스 이용 --");
		System.out.println(s);
	}
	
	public void destroy() {
		System.out.println("객체 소멸전 작업은 여기서...");
	}
	
	
	
}

 

 

✔️ setter 로 의존성 주입

: setter 메소드를 통해 의존관계가 있는 Bean 을 주입하거나 고정된 문자열이나 정수 같은 기본형 데이터를 주입할 수 있다.

: setter 메소드에 값을 전달하기 위해 <propertry> 엘리먼트를 사용한다.

: 메소드 이름은 네이밍 패턴을 따르는 것이 좋다.

 

📓 <property> 엘리먼트

- setter 메소드를 통해 의존관계가 있는 Bean 을 주입하려면 <property> 태그의 ref 속성을 사용하거나 하위 태그인 <ref> 태그를 사용한다.

- setter 메소드를 통해 문자열, 정수 등 단순 값을 주입할 때는 <property> 태그의 value 속성을 사용하거나 하위 태그인 <value> 태그를 사용한다.

 

-- applicationContext.xml

✨ setter 의존성 주입은 실행 중에 주입된 값을 변경할 수 있다.

✨ setter 는 name 속성의 이름을 기준으로 첫글자를 대문자로하여 set 을 붙인 메소드이다.

<!-- setter 를 이용한 프로퍼티 설정(문자열 또는 기본 자료형) -->
<bean id="userService" class="com.user3.UserServiceImpl">
    <property name="name" value="스프링"/>
    <property name="tel" value="010-1111-2222"/>
    <property name="age" value="20"/>
</bean>

<bean id="userService2" class="com.user3.UserServiceImpl2">
    <property name="name" value="스프링2"/>
    <property name="tel" value="010-1111-3333"/>
    <property name="age" value="17"/>
</bean>

<!-- setter 를 이용한 의존성 주입 -->
<!-- setter 주입은 프로그램 실행중 주입된 값을 변경할 수 있지만, 생성자 주입은 변경 불가 -->
<!-- 
    반드시 setter가 존재 해야한다.
    setter 는 name속성의 이름을 기준으로 첫글자를 대문자로하여 set을 붙인 메소드
    name="userService" => setUserService
 -->
 <bean id="user" class="com.user3.User">
    <property name="userService" ref="userService2"/>
 </bean>

 

-- setter 를 이용해 의존성을 주입할 때는 setter 가 반드시 존재해야한다.

public class UserServiceImpl implements UserService {
	private String name;
	private String tel;
	private int age;
	

	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}


	public String getTel() {
		return tel;
	}


	public void setTel(String tel) {
		this.tel = tel;
	}


	public int getAge() {
		return age;
	}


	public void setAge(int age) {
		this.age = age;
	}


	@Override
	public String message() {
		String s = age >= 19 ? "성인" : "미자";
		
		String result = name + ", " + tel + ", " + age + ", " + s;
		return result;
	}
	
}

 

 

: p 네임스페이스를 이용한 프로퍼티 설정

XML의 p 네임스페이스를 이용하여 <property> 태그 대신 setter 메소드의 매개변수 설정이 가능하다.

<beans> 의 루트 태그에 네임스페이스 설정 필수 ✨

 

📓 형식

<bean id="빈아이디" class="패키지명.클래스" p:프로퍼티명-ref="설정할 빈 아이디"... >

 

-- applicationContext.xml

✨ p 네임스페이스를 이용할 때, ref 는 설정할 bean 아이디를 말한다.

✨ userService 라는 id 를 가진 네임스페이스를 이용하여 setter 메소드의 매개변수를 설정했다.

<!-- setter 를 이용한 프로퍼티 설정(문자열, 기본 자료형) : p 네임스페이스 -->
<bean id="userService" class="com.user4.UserServiceImpl"
    p:name="너자바" p:tel="010-9898-8989" p:age="20"/>

<!--  setter 를 이용한 의존성 주입 : p 네임스페이스 -->
<bean id="user" class="com.user4.User"
    p:userService-ref="userService"/>

 

 

✔️ setter 로 의존성 주입 - 컬렉션 타입 프로퍼티 설정

: 프로퍼티 타입이 컬렉션 타입인 경우 다음 태그를 사용하여 설정한다.

<list> <map> <set> <props> 등

: 컬렉션의 제너릭 타입이 레퍼런스인 경우에는 <ref> , <bean> 태그를 사용하여 객체를 참조하며, 고정된 문자열이나 정수 등 기본 타입은 <value> 태그, null은 <null> 태그를 사용한다.

 

<list> : 자바의 list 배열 값 목록을 전달한다.

<set> : 자바의 set 타입의 값 목록을 전달한다.

<map> : 자바의 map 타입의 <키,값> 타입의 목록을 전달한다. <entry> 태그를 사용하여 저장될 한 개의 <키, 값>을 표현한다.

<props> : 자바의 프로퍼티 타입에 키, 값 목록을 전달한다. 키와 값 모두 String 이다. <prop> 태그를 이용하여 프로퍼티 값을 설정한다.

 

-- applicationContext.xml

✨ <props> 태그는 <prop> 태그를 이용한다. 

✨ <props> 즉 Properties는 키와 값 모두 String 만 가능하다.

✨ <map> 에서 키나 값이 문자가 아닌 객체라면, ref 를 붙이면 된다.

<bean id="userService" class="com.user5.UserServiceImpl">
    <property name="name" value="컬렉션"/>
    <property name="address">
        <map>
            <entry key="김자바" value="서울"/>		<!-- 만약, 키나 값이 객체라면 ref 를 붙이면 된다. <entry key-ref="김자바" value-ref="서울"/> -->
            <entry>
                <key><value>너자바</value></key>
                <value>경기</value>
            </entry>
        </map>
    </property>
    <property name="hobby">
        <list>
            <value>게임</value> <!-- <ref bean="객채"/> -->
            <value>영화</value>
            <value>여행</value>
        </list>
    </property>
    <property name="tels">
        <props>  <!-- Properties는 키와 값 모두 String 만 가능하다. -->
            <prop key="하하하">010-1111-2222</prop>
            <prop key="나나나">010-2222-2222</prop>
            <prop key="도도도">010-3333-2222</prop>
        </props>
    </property>

</bean>

<bean id="user" class="com.user5.User">
    <property name="userService" ref="userService"/>
</bean>

 

-- UserServiceImpl 부분

✨ properties 는 Iterator<Object> 사용

public class UserServiceImpl implements UserService {
	private String name;
	private Map<String, String> address;
	private List<String> hobby;
	private Properties tels;
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Map<String, String> getAddress() {
		return address;
	}

	public void setAddress(Map<String, String> address) {
		this.address = address;
	}

	public List<String> getHobby() {
		return hobby;
	}

	public void setHobby(List<String> hobby) {
		this.hobby = hobby;
	}

	public Properties getTels() {
		return tels;
	}

	public void setTels(Properties tels) {
		this.tels = tels;
	}

	
	@Override
	public String message() {
		String s = "이름 : " + name + "...\n";
		s += " ------------------------------ \n";
		s += "친구 주소록 ... \n";
		
		//map
		Iterator<String> it = address.keySet().iterator();
		while(it.hasNext()) {
			String n = it.next();
			String v = address.get(n);
			s += n + " : " + v + "\n";
		}
		
		s += " ------------------------------ \n";
		
		s += "전화번호... \n";
		
		//property
		Iterator<Object> it2 = tels.keySet().iterator();
		while(it2.hasNext()) {
			String n = (String)it2.next();
			String v = tels.getProperty(n);
			s += n + " : " + v + "\n";
		}
		
		s += " ------------------------------ \n";
		
		s += "취미... \n";
		
		//list
		for(String h : hobby) {
			s += h + "  ";
		}
		
		s += " ------------------------------ \n";
		
		
		return s;
	}
	
	

}

 

 

✔️ 의존 관계 자동 설정 (auto-wiring>

: 의존하는 빈 객체의 타입이나 이름을 이용하여 컨테이너가 의존성 주입을 자동으로 설정한다. 

bean 태그의 autowire 속성을 이용해 모드를 지정한다.

스프링 5.1부터 정상 동작 하지만 , deprecated 되었다.

 

📓 자동 설정 모드

no : 기본값으로 자동 빈 설정을 하지 않는다.

byName : 프로퍼티와 같은 이름을 선택해 의존성을 주입한다.

byType : 프로퍼티와 같은 타입을 갖는 bean 을 찾아 주입한다. 해당 모드는 의존객체가 하나만 존재할 때 사용 가능하다. 

constructor : 생성자를 통해 주입하는 모드이다.

 

-- applicationContext.xml

✨ 자동으로 의존성 주입하는 것은 권장하진 않는다.

<bean id="userService" class="com.user6.UserServiceImpl">
    <property name="name" value="가가가"/>
    <property name="tel" value="010-1111-1111"/>
    <property name="age" value="20"/>
</bean>

<!-- 자동으로 의존성 주입하기  (권장하진 않는다!) -->
<!-- 
    byName : 프로퍼티와 동일한 이름의 빈을 찾아 주입(setter injection)
    byType : 프로퍼티와 동일한 타입의 빈을 찾아 주입(setter injection). 동일타입이 하나인 경우에만 사용가능
 -->
<bean id="user" class="com.user6.User" autowire="byType"/>

 

 

✔️ 프로퍼티 파일을 이용한 값 설정

: 프로퍼티 파일을 이용해 값을 설정하는건 다음 중 하나의 방법을 사용한다. 

1) PropertyPlaceholderConfigurer 클래스를 빈으로 등록

2) <context:property-placeholder> 태그 사용

 

-- applicationContext.xml

✨ 1) Properties 파일을 로드한다.

✨ 2) 프로퍼티 값을 할당한다. => ${ } 안에 프로퍼티 파일 값의 이름을 가져온다.

✨ 3) 의존성을 주입한다. 끝!

<!-- Properties 파일 로드 -->
<context:property-placeholder location="classpath:com/prop/user.properties"/>

<!-- 프로퍼티 값을 할당 -->
<bean id="userService" class="com.prop.UserServiceImpl">
    <property name="name" value="${join.name}"/>
    <property name="tel" value="${join.tel}"/>
    <property name="age" value="${join.age}"/>
</bean>

<!--  의존성 주입만 하면 끝!  -->
<bean id="user" class="com.prop.User">
    <property name="userService" ref="userService" />
</bean>

 

 

 

블로그의 정보

개발자 미니민의 개발로그

mini_min

활동하기