๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Spring

[Spring] @Autowired์˜ ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ ๋ฐฉ๋ฒ• - required, Primary, Qualifier

by Leica 2020. 3. 1.
๋ฐ˜์‘ํ˜•

[Spring] @Autowired์˜ ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ ๋ฐฉ๋ฒ• - required, Primary, Qualifier

1. ์˜์กด๊ฐ์ฒด ํƒ€์ž…์˜ ๋นˆ์ด ์—†๋Š” ๊ฒฝ์šฐ

๋‹ค์Œ๊ณผ ๊ฐ™์ด BookService ํด๋ž˜์Šค์™€ BookRepository ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์žˆ๋‹ค.

 

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
@Service
public class BookService {
 
    BookRepository bookRepository;
 
    @Autowired
    public BookService(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }
}
 
//
 
public interface BookRepository {
}
cs

 

BookService ํด๋ž˜์Šค์—๋Š” @Service ์• ๋…ธํ…Œ์ด์…˜์„ ๋ถ™์—ฌ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ด์ฃผ์—ˆ๊ณ  BookRepository๋Š” ์• ๋…ธํ…Œ์ด์…˜์„ ๋ถ™์ด์ง€ ์•Š์€ ์ผ๋ฐ˜ ์ž๋ฐ” ํด๋ž˜์Šค์ด๋‹ค.

BookRepository๋Š” BookService์˜ ์˜์กด๊ฐ์ฒด์ด๋ฉฐ @Autowired๋ฅผ ๋ถ™์—ฌ BookService์˜ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ฃผ์ž…๋ฐ›๋„๋ก ํ•˜์˜€๋‹ค.

 

์ด๋Œ€๋กœ ์‹คํ–‰ํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค.

 

BookService ๋นˆ์„ ์ƒ์„ฑํ•˜๋ ค๋ฉด BookRepository ๋นˆ์ด ํ•„์š”ํ•œ๋ฐ IoC ์ปจํ…Œ์ด๋„ˆ์—์„œ ํ•ด๋‹นํ•˜๋Š” ํƒ€์ž…์˜ ๋นˆ์„ ์ฐพ์„ ์ˆ˜ ์—†์œผ๋‹ˆ BookRepository๋ฅผ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๋ผ๋Š” ๋œป์ด๋‹ค.

 

์ฝ”๋“œ๋ฅผ ๋ฐ”๊ฟ” ์ด๋ฒˆ์—” setter๋กœ ์ฃผ์ž…๋ฐ›๋„๋ก ํ•ด๋ณด์ž.

 

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
@Service
public class BookService {
 
    BookRepository bookRepository;
 
    @Autowired
    public void setBookRepository(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }
}
 
//
 
public interface BookRepository {
}
cs

 

์‹คํ–‰ํ•˜๋ฉด ์—ญ์‹œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

 

์ƒ์„ฑ์ž๋กœ ์ฃผ์ž…๋ฐ›๋˜ ๊ฒƒ๊ณผ ๋‹ฌ๋ฆฌ Setter๋กœ ์ฃผ์ž…๋ฐ›๋„๋ก ํ–ˆ๊ธฐ๋•Œ๋ฌธ์— ์›๋ž˜๋Š” BookService์˜ ์ธ์Šคํ„ด์Šค๋Š” ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š”๊ฒŒ ๋งž์ง€๋งŒ @Autowired ์• ๋…ธํ…Œ์ด์…˜์— ์˜ํ•ด BookRepository๋ฅผ ์ฃผ์ž…๋ฐ›๋„๋ก ์„ค์ •ํ•œ BookService๋„ ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์ด๋‹ค.

 

์ด๋ ‡๊ฒŒ @Autowired ์• ๋…ธํ…Œ์ด์…˜์„ ์ฒ˜๋ฆฌํ•˜๋˜ ์ค‘ ํ•ด๋‹นํ•˜๋Š” ๋นˆ์˜ ํƒ€์ž…์„ ๋ชป์ฐพ๊ฑฐ๋‚˜ ์˜์กด์„ฑ ์ฃผ์ž…์„ ํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ์—๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉฐ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ๋™์ด ์ œ๋Œ€๋กœ ๋˜์ง€ ์•Š๋Š”๋‹ค.

 

@Autowired์— required ์†์„ฑ๊ฐ’์„ ์ถ”๊ฐ€ํ•ด๋ณด์ž.

 

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
@Service
public class BookService {
 
    BookRepository bookRepository;
 
    @Autowired(required = false)
    public void setBookRepository(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }
}
 
//
 
public interface BookRepository {
}
cs

 

์ด๋ฒˆ์—” ์—๋Ÿฌ ์—†์ด ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค.

 

@Autowired(required = false)์€ ์˜์กด์„ฑ์„ 'Optional'๋กœ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

 

์ฃผ์ž…๋ฐ›์„ ์˜์กด๊ฐ์ฒด๊ฐ€ ํ•„์ˆ˜์ ์ด์ง€ ์•Š์„ ๊ฒฝ์šฐ @Autowired(required = false)๋กœ ์„ค์ •ํ•ด์„œ ์˜์กด๊ฐ์ฒด๋ฅผ ์ฃผ์ž…๋ฐ›์ง€ ๋ชปํ•˜๋”๋ผ๋„ ๋นˆ์„ ์ƒ์„ฑํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ฒฐ๊ณผ์ ์œผ๋กœ BookService๋Š” BookRepository๋ฅผ ์ฃผ์ž…๋ฐ›์ง€ ์•Š์€ ์ƒํƒœ๋กœ IoC ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋ก๋œ๋‹ค.

required ์†์„ฑ์˜ ๊ธฐ๋ณธ๊ฐ’์€ true์ด๊ธฐ ๋•Œ๋ฌธ์— ์ง€์ •ํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ setter๋กœ ์ฃผ์ž…๋ฐ›๊ฒŒ ํ–ˆ๋”๋ผ๋„ ์˜์กด๊ฐ์ฒด๋ฅผ ์ฃผ์ž…๋ฐ›์ง€ ๋ชปํ•˜๋ฉด ํ•ญ์ƒ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

 

required = false๋Š” @Autowired๋ฅผ ํ•„๋“œ๋‚˜ setter์— ๋ถ™์˜€์„ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

2. ์˜์กด๊ฐ์ฒด ํƒ€์ž…์˜ ๋นˆ์ด ์—ฌ๋Ÿฌ๊ฐœ์ธ ๊ฒฝ์šฐ

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
@Service
public class BookService {
 
    @Autowired
    BookRepository bookRepository;
}
 
//
 
public interface BookRepository {
}
 
//
 
import org.springframework.stereotype.Repository;
 
@Repository
public class MyBookRepository implements BookRepository {
}
 
//
 
import org.springframework.stereotype.Repository;
 
@Repository
public class AnotherBookRepository implements BookRepository {
}
cs

BookService์—์„œ BookRepository๋ฅผ ํ•„๋“œ๋กœ ์ฃผ์ž…๋ฐ›๋„๋ก ๋ณ€๊ฒฝํ•œ๋‹ค.

MyBookRepository, AnotherBookRepository ํด๋ž˜์Šค๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค๊ณ  BookRepository๋ฅผ ๊ตฌํ˜„ํ•˜๋„๋ก ํ•œ๋‹ค.

๋‘˜ ๋‹ค @Repository๋ฅผ ๋ถ™์—ฌ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•จ์œผ๋กœ์จ BookRepository ํƒ€์ž…์˜ ๋นˆ์ด ๋‘๊ฐœ๊ฐ€ ๋˜์—ˆ๋‹ค.

 

์ด ๊ฒฝ์šฐ spring์€ BookService์— ์–ด๋–ค BookRepository ๋นˆ์„ ์ฃผ์ž…ํ•ด์ค„๊นŒ?

 

๊ฒฐ๊ณผ๋Š” ์ฃผ์ž…ํ•ด ์ค„ ์ˆ˜ ์—†๋‹ค.

๋‘ BookRepository์ค‘ ์–ด๋–ค ๋นˆ์„ ์›ํ•˜๋Š”์ง€ spring ์ž…์žฅ์—์„œ ์•Œ ์ˆ˜๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

1) @Primary

@Primary ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด์„œ ํ•ด๋‹นํ•˜๋Š” ํƒ€์ž…์˜ ๋นˆ์ด ์—ฌ๋Ÿฌ๊ฐœ์ผ ๊ฒฝ์šฐ ์šฐ์„ ์ ์œผ๋กœ ์ฃผ์ž…ํ•  ๋นˆ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

MyBookRepository์— @Primary ์• ๋…ธํ…Œ์ด์…˜์„ ๋ถ™์ด์ž.

 

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
@Service
public class BookService {
 
    @Autowired
    BookRepository bookRepository;
}
 
//
 
public interface BookRepository {
}
 
//
 
import org.springframework.stereotype.Repository;
 
@Repository @Primary
public class MyBookRepository implements BookRepository {
}
 
//
 
import org.springframework.stereotype.Repository;
 
@Repository
public class AnotherBookRepository implements BookRepository {
}
cs

 

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด spring์€ BookService์— BookRepository๋ฅผ ์ฃผ์ž…ํ• ๋•Œ ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋นˆ์ด ์กด์žฌํ•  ๊ฒฝ์šฐ @Primary ์• ๋…ธํ…Œ์ด์…˜์ด ๋ถ™์–ด์žˆ๋Š” ๋นˆ์„ ์ฃผ์ž…ํ•ด์ค€๋‹ค.

 

2) Qualifier

@Qualifier ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด์„œ ๋นˆ id๋ฅผ ์ง€์ •ํ•ด์„œ ์ฃผ์ž…๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฃผ์ž…๋ฐ›๋Š” ๊ณณ์— @Qualifier ์• ๋…ธํ…Œ์ด์…˜์„ ์ถ”๊ฐ€ํ•˜์ž.

 

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
@Service
public class BookService {
 
    @Autowired @Qualifier("myBookRepository")
    BookRepository bookRepository;
}
 
//
 
public interface BookRepository {
}
 
//
 
import org.springframework.stereotype.Repository;
 
@Repository
public class MyBookRepository implements BookRepository {
}
 
//
 
import org.springframework.stereotype.Repository;
 
@Repository
public class AnotherBookRepository implements BookRepository {
}
cs

 

๊ธฐ๋ณธ์ ์œผ๋กœ @Repository ์• ๋…ธํ…Œ์ด์…˜์„ ์“ฐ๋ฉด ๋นˆ id๋Š” ์†Œ๋ฌธ์ž๋กœ ์‹œ์ž‘ํ•˜๋Š” ํด๋ž˜์Šค ์ด๋ฆ„๊ณผ ๋™์ผํ•˜๋‹ค.

๋”ฐ๋ผ์„œ MyBookRepository๋ฅผ ์ฃผ์ž…๋ฐ›๋„๋ก ์„ค์ •ํ•˜๋ ค๋ฉด Qualifier ์• ๋…ธํ…Œ์ด์…˜์— myBookRepository๋ผ๊ณ  ์ง€์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

 

์ด๋ ‡๊ฒŒ @Primary์™€ @Qualifier ์• ๋…ธํ…Œ์ด์…˜์€ ๊ฐ™์€ ๋ชฉ์ ์œผ๋กœ ์“ธ ์ˆ˜ ์žˆ์ง€๋งŒ @Primary๊ฐ€ ๋” type safeํ•œ ๋ฐฉ๋ฒ•์ด๋‹ค.

 

3) ํ•ด๋‹นํ•˜๋Š” ํƒ€์ž…์˜ ๋นˆ์„ ๋ชจ๋‘ ์ฃผ์ž…๋ฐ›๊ธฐ

BookService์—์„œ BookRepository๋ฅผ ์ฃผ์ž…๋ฐ›๋Š” ๋ณ€์ˆ˜์˜ ํƒ€์ž…์„ List๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.

 

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import java.util.List;
 
@Service
public class BookService {
 
    @Autowired
    List<BookRepository> bookRepositories;
}
 
//
 
public interface BookRepository {
}
 
//
 
import org.springframework.stereotype.Repository;
 
@Repository
public class MyBookRepository implements BookRepository {
}
 
//
 
import org.springframework.stereotype.Repository;
 
@Repository
public class AnotherBookRepository implements BookRepository {
}
cs

 

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด spring์€ BookRepository ํƒ€์ž…์˜ ๋นˆ์„ ๋ชจ๋‘ ์ฃผ์ž…ํ•ด์ค€๋‹ค.

 

4) ๋นˆ id์™€ ๋ณ€์ˆ˜๋ช…์„ ๋™์ผํ•˜๊ฒŒ

๋ณ„๋กœ spring์—์„œ ์ถ”์ฒœํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์•„๋‹ˆ์ง€๋งŒ @Autowired๋Š” ํƒ€์ž…์„ ๋ณด๊ณ  ๋‚˜์„œ ์—ฌ๋Ÿฌ ๊ฐœ์ผ ๊ฒฝ์šฐ ๋ณ€์ˆ˜๋ช…๊ณผ ๋นˆ id๋„ ํ™•์ธํ•˜๋Š” ๊ณผ์ •์„ ๊ฑฐ์นœ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด ์ง€๊ธˆ์ฒ˜๋Ÿผ BookRepository ํƒ€์ž…์˜ ๋นˆ์ด MyBookRepository, AnotherBookRepository๊ฐ€ ์กด์žฌํ•˜๋Š” ์ƒํƒœ์—์„œ MyBookRepository๋ฅผ ์ฃผ์ž…๋ฐ›๊ณ  ์‹ถ์œผ๋ฉด ์ฃผ์ž…๋ฐ›์„ ๋ณ€์ˆ˜๋ช…์„ myBookRepository๋กœ ํ•˜๋ฉด ๋œ๋‹ค.

 

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
@Service
public class BookService {
 
    @Autowired
    BookRepository myBookRepository;
}
 
//
 
public interface BookRepository {
}
 
//
 
import org.springframework.stereotype.Repository;
 
@Repository
public class MyBookRepository implements BookRepository {
}
 
//
 
import org.springframework.stereotype.Repository;
 
@Repository
public class AnotherBookRepository implements BookRepository {
}
cs

 

์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋นˆ ์ค‘์—์„œ ๋ณ€์ˆ˜๋ช…๊ณผ ๋นˆ id๊ฐ€ ๋™์ผํ•œ ๋นˆ์ด ์ฃผ์ž…๋œ๋‹ค.

 

References

์ธํ”„๋Ÿฐ - ๋ฐฑ๊ธฐ์„ ๋‹˜์˜ ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ ํ•ต์‹ฌ ๊ธฐ์ˆ 

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€