예제 소스 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

<!-- BookStore.class -->

public interface BookStore {

}

<!-- NobleBookStore.class -->

@Service
public class NobleBookStore implements BookStore {

}

<!-- EssayBookStore.class -->

@Service
public class EssayBookStore implements BookStore {

}

중복된 의존주입

동일한 타입의 Bean을 의존 주입 받으려고 하면 문제가 발생합니다(동일한 타입의 Bean 등록에는 문제가 없다).

1
2
3
4
5
6
7
8
9
@Component
public class City {
@Autowired
BookStore bookStore;

public BookStore getBookStore() {
return bookStore;
}
}
1
Error creating bean with name 'city': Unsatisfied dependency expressed through field 'bookStore'

동일한 타입의 Bean이 2개가 존재하기 때문에 위와 같은 에러가 발생합니다.


해결방법

@Primary 어노테이션 사용

우선적으로 의존 주입하고 싶은 class에 @Primary 어노테이션을 사용합니다.

1
2
3
4
5
@Service
@Primary
public class NobleBookStore implements BookStore {

}
1
2
3
4
5
6
7
8
9
public class TestControllerTest {

@Test
public void test() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);
System.out.println(((City)applicationContext.getBean("city")).getBookStore());

}
}
1
kr.co.spring.NobleBookStore@16e7dcfd

@Qulifier 어노테이션 사용

@Autowired와 함께 사용하며 사용하고자 하는 빈의 아이디를 적어주면 됩니다(빈의 아이디를 따로 설정하지 않으면 default로 class 명에 첫글자가 소문자인 아이디로 설정된다).

1
2
3
4
5
6
@Component
public class City {
@Autowired
@Qualifier("nobleBookStore")
BookStore bookStore;
}

@Qulifier 어노테이션 사용하지 않기

기본적으로 @Autowried는 타입으로 의존주입을 해주지만 타입이 존재하지 않으면 Bean Name으로도 의존주입이 가능합니다. 그래서 굳이 @Qulifier를 사용하지 않아도 사용이 가능합니다.

아래의 코드를 보면 이해가 가능합니다.

1
2
3
4
5
@Component
public class City {
@Autowired
BookStore nobleBookStore; // 기존에 bookStore 대신 nobleBookStore를 사용하과 있다.
}

동일한 타입의 Bean 모두 의존주입 받기

동일한 타입의 Bean들을 모두 의존주입을 받을수가 있습니다.

1
2
3
4
5
@Component
public class City {
@Autowired
List<BookStore> bookRepoitories;
}

Comment and share

@Autowried는 Bean으로 등록된 객체를 자동으로 삽입해주는 역할을 합니다. 생성자, 필드, set메소드를 활용 하여 적용이 가능합니다.

예제 Class 등록

해당 포스팅 시에 사용 할 Book 클래스입니다. 아래에서 사용 될 Book 클래스는 아래 소스 코드를 사용하게 됩니다.

1
2
3
4
5
6
7
8
package kr.co.spring;

import org.springframework.stereotype.Component;

@Component
public class Book {

}

생성자를 이용한 방법

생성자 메소드 위에 @Autowired만 등록 해서 사용 하면 됩니다.

1
2
3
4
5
6
7
8
9
@Component
class BookStore {
private Book book;

@Autowired
public BookStore(Book book) {
this.book = book;
}
}

생성자에서 @Autowired는 생략이 가능합니다.


setter를 이용한 방법

setter 메소드 위에 @Autowired만 등록 해서 사용 하면 됩니다. 생성자와는 달리 @Autowired를 붙여주지 않으면 의존주입이 되지 않습니다.

1
2
3
4
5
6
7
8
9
@Component
class BookStore {
private Book book;

@Autowired
public setBook(Book book) {
this.book = book;
}
}

setter를 활용하면 Bean을 필수적으로 의존주입 받을지 여부를 선택할수 있습니다. 옵션을 주지 않는 경우 의존주입 받을 Bean이 없는 경우 에러가 발생합니다. 이때 @Autowired(required = false)를 사용해서 만약 Bean이 존재하지 않는 경우 의존주입을 받지 않도록 설정이 가능합니다.

setter 메소드 이름은 상관이 없습니다.


필드에 직접 사용

필드 위에 @Autowired를 등록해서 사용이 가능합니다. 가장 심플하게 코드를 작성할수 있습니다. setter와 마찬가지로 required 옵션을 사용가능합니다.

1
2
3
4
5
@Component
class BookStore {
@Autowired
private Book book;
}
외부 라이브러리를 Bean 등록하고 의존주입

수정이 불가능한 외부라이브러리를 Bean으로 등록하고 해당 Bean에 의존주입까지 해주어야 하는 경우가 있습니다.

1
2
3
4
<bean id="library" class="kr.co.spring.Library">
<constructor-arg value="라이브러리"/>
<property name="location" value="서울"/>
</bean>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Library {
private String name;
private String location;

public Library(String name) {
this.name = name;
}

public void setLocation(String location) {
this.location = location;
}

@Override
public String toString() {
return "Library{" +
"name='" + name + '\'' +
", location='" + location + '\'' +
'}';
}
}
1
2
3
4
5
6
7
8
9
public class TestControllerTest {

@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring/spring-bean.xml");
Library library = (Library) applicationContext.getBean("library");
System.out.println(library.toString());
}
}
1
Library{name='라이브러리', location='서울'}

만약 생성자에서 파라미터를 여러개 받는 경우에는 index를 이용하면 됩니다.

1
2
3
4
5
6
7

<bean id="library" class="kr.co.spring.Library">
<constructor-arg index="0" value="1"/>
<constructor-arg index="1" value="라이브러리"/>

<property name="location" value="서울"/>
</bean>

type 속성을 이용해서도 사용 가능합니다.

1
2
3
4
5
6
<bean id="library" class="kr.co.spring.Library">
<constructor-arg value="1" type="int"/>
<constructor-arg value="라이브러리" type="java.lang.String"/>

<property name="location" value="서울"/>
</bean>

예제에서는 value를 사용하였지만 bean을 의존주입 받을 때는 ref를 사용하면 됩니다.

Comment and share

  • page 1 of 1

Moon Star

author.bio


author.job