[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();
}
}
}
'Spring' 카테고리의 다른 글
[spring] bean Scopes 빈 객체 범위 정의 (0) | 2022.11.09 |
---|---|
[spring] 의존성 주입 - 생성자, setter, 프로퍼티 파일 (0) | 2022.11.09 |
[spring] 주요 인터페이스, 의존성 주입 개념 (0) | 2022.11.08 |
[spring] DI (Dependency Injection) 의존성 주입 (0) | 2022.11.08 |
[spring] 스프링 개념 - 스프링 프레임워크란? (0) | 2022.11.08 |
블로그의 정보
개발자 미니민의 개발로그
mini_min