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

[spring] <bean> 태그, 생성자 의존성 주입 방법

by mini_min
[spring] <bean> 태그, 생성자 의존성 주입 방법

<beans> </beans> 루트 엘리먼트
스프링 XML 설정의 최상위 태그

<import> 엘리먼트
분리하여 작성한 설정 파일들을 하나로 통합할 때 사용하는 엘리먼트이다.

<bean> 엘리먼트
스프링 컨테이너에 빈을 정의한다. (객체를 만든다.)

 

👩‍💻 속성
id : 빈의 id 설정. 유일해야한다! 자바 코드에서 getBean() 으로 빈을 가져오거나 주입 설정에서 ref 속성으로 빈을 참조하는 경우 사용한다. 
class : 빈으로 등록할 클래스 설정(필수). 
패키지명을 포함한 클래스명을 지정한다. 
name : id와 같은 기능을 하지만, 자바 식별자 규칙을 따르지 않는 문자열도 가능하다. 
✨ 스프링은 기본이 singleton 이다.

<bean> 의 하위 엘리먼트
<constructor-arg>, <property> 등
✨ <constructor-arg> 는 생성자의 매개변수 만큼 설정해야한다.

 


* DI 는 디자인 패턴 중 하나다.
객체 간의 의존성을 자신이 아닌 외부에서 받아 느슨한 결합을 하여 유연성, 재사용성, 테스트 용이성을 개선시킨다.
- 의존성 주입 방법
Constructor Injection : 생성자를 이용한 의존성 주입
Method Injection : setter 나 일반 메소드를 이용한 의존성 주입
Field Injection : 필드를 통한 의존성 주입 (어노테이션 이용)

✨ 생성자를 이용한 의존성 주입을 가장 밀고 있다고 함
✨ 생성자를 이용해 의존성을 주입하면 쉽게 변경이 불가하여 안전하다.

1) 생성자를 이용한 의존성 주입
- 생성자 주입은 생성자로 객체를 생성하는 시점에 필요한 빈을 주입한다.
- 생성자 주입은 순환 참조를 방지할 수 있다.
- 불변성
: 필드 주입과 수정자 주입은 해당 필드를 final 로 선언할 수 없다.
: 생성자 주입은 생성자의 인수를 이용하여 필드를 초기화 하므로 필드를 final 로 선언할 수 있다. 

- <constructor-arg> 엘리먼트
: 컨테이너가 기본 생성자가 아닌 매개변수가 존재하는 생성자를 호출할 수 있도록 설정한다.
- ref : 객체. 다른 객체의 아이디나 이름 참조
- value : 고정 문자열이나 숫자
index, name, type 으로 전달 받을 매개변수 설정한다.

package com.user1;

public class UserServiceImpl implements UserService {
	private String name;
	private String tel;
	private int age;
	
	public UserServiceImpl() {
		this.name = "김자바";
		this.tel = "010-1111-1111";
		this.age = 20;
	}
	
	@Override
	public String message() {
		String s = age >= 19 ? "성인" : "미자";
		
		String result = name + ", " + tel + ", " + age + ", " + s;
		return result;
	}
	
}
package com.user1;

public class User {
	private UserService userService;
	
	//UserService 객체를 생성한 것이 없는데 결과 나옴
	//생성한 객체를 외부 spring 에서 만들고 가져온 것
	//User 는 인터페이스 UserService 에 의존성을 가지고 있다.
	//클래스에 의존성을 준 관계로 코드를 짜면, 변경시에 클래스를 모두 변경해야한다. 인터페이스에 의존성을 주면, 소스 고치는게 없다. 스프링이 외부에서 객체 만들어주고 생성해주기때문에
	//클래스에 의존성 주면 소스 전체 변경하는 일이 발생할 수 있음. 인터페이스에 의존성을 줘야한다. 
	public User(UserService userService) {
		this.userService = userService;
	}
	
	//인터페이스 UserService에 의존성 가짐
	public void write() {
		String s = userService.message();
		
		System.out.println("--생성자를 이용한 의존성 주입--");
		System.out.println(s);
	}
	
}
<!-- bean 태그 : 스프링 컨테이너에 빈을 정의(객체 생성) -->	
	
	<!-- 기본 생성자를 이용한 빈 정의 -->
	<bean id="userService" class="com.user1.UserServiceImpl"/>
	
	<!-- 
	<bean id="userService2" class="com.user1.UserServiceImpl2">
		<constructor-arg value="너자바"/>
		<constructor-arg value="010-1111-3333"/>
		<constructor-arg value="20"/>
	</bean>
	 -->
	 
	 <!-- 
	 <bean id="userService2" class="com.user1.UserServiceImpl2">
	 	<constructor-arg index="1" value="010-1111-3333"/>
		<constructor-arg index="0" value="너자바"/>
		<constructor-arg index="2" value="20"/>
	</bean>
	 -->
	 
	 <bean id="userService2" class="com.user1.UserServiceImpl2">
	 	<constructor-arg name="tel" value="010-1111-3333"/>
		<constructor-arg name="name" value="너자바"/>
		<constructor-arg name="age" value="20"/>
	</bean>
	 
	
	<!-- 인자가 하나인 생성자를 이용하여 빈을 정의 -->
	<!-- 생성자를 이용하여 의존성을 주입 -->
	<!--  id 같으면 안된다 아아아  -->
	<!-- 인자가 없는 기본 생성자가 없으면 안돼서  constructor-arg ref="userService" -->
	<bean id="user" class="com.user1.User">
		<constructor-arg ref="userService2"/>
	</bean>
package com.user1;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

public class App {

	public static void main(String[] args) {
		// 스프링 컨테이너 
		AbstractApplicationContext context = 
				new GenericXmlApplicationContext("classpath:com/user1/applicationContext.xml");
		
		try {
			//빈으로 객체 2개 만들었고, 그 중에서 id가 user 인 객체 가져옴
			User obj = (User)context.getBean("user");
			obj.write();
			
		} finally {
			context.close();
		}
	}

}



 

 

블로그의 정보

개발자 미니민의 개발로그

mini_min

활동하기