DI Annotation

kailynยท2024๋…„ 9์›” 24์ผ

SpringFramework

๋ชฉ๋ก ๋ณด๊ธฐ
4/7

1. @Autowired

๐Ÿ’ก @Autowired ์–ด๋…ธํ…Œ์ด์…˜์€ Type์„ ํ†ตํ•œ DI๋ฅผ ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์•Œ์•„์„œ ํ•ด๋‹น ํƒ€์ž…์˜ Bean์„ ์ฐพ์•„์„œ ์ฃผ์ž…ํ•ด์ค€๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ๋Š” ํ…Œ์ŠคํŠธ์— ๊ณตํ†ต์ ์œผ๋กœ ์‚ฌ์šฉ ํ•  BookDTO, BookDAO, BookDAOImpl ํด๋ž˜์Šค์ด๋‹ค.

  1. BookDTO

    @Data
    @AllArgsConstructor
    public class BookDTO {
    
        private int sequence;        //๋„์„œ๋ฒˆํ˜ธ
        private int isbn;            //isbn
        private String title;        //์ œ๋ชฉ
        private String author;       //์ €์ž
        private String publisher;    //์ถœํŒ์‚ฌ
        private Date createdDate;    //์ถœํŒ์ผ
    
    }
  2. BookDAO

    public interface BookDAO {
    
        /* ๋„์„œ ๋ชฉ๋ก ์ „์ฒด ์กฐํšŒ */
        List<BookDTO> selectBookList();
    
        /* ๋„์„œ ๋ฒˆํ˜ธ๋กœ ๋„์„œ ์กฐํšŒ */
        BookDTO selectOneBook(int sequence);
    }
  3. BookDAOImpl

    /* @Repository : @Component์˜ ์„ธ๋ถ„ํ™” ์–ด๋…ธํ…Œ์ด์…˜์˜ ํ•œ ์ข…๋ฅ˜๋กœ DAO ํƒ€์ž…์˜ ๊ฐ์ฒด์— ์‚ฌ์šฉํ•œ๋‹ค. */
    @Repository("bookDAO")
    public class BookDAOImpl implements BookDAO {
    
        private Map<Integer, BookDTO> bookList;
    
        public BookDAOImpl() {
            bookList = new HashMap<>();
            bookList.put(1, new BookDTO(1, 123456, "์ž๋ฐ”์˜ ์ •์„", "๋‚จ๊ถ์„ฑ", "๋„์šฐ์ถœํŒ", new Date()));
            bookList.put(2, 
    					new BookDTO(2, 654321, "์นญ์ฐฌ์€ ๊ณ ๋ž˜๋„ ์ถค์ถ”๊ฒŒ ํ•œ๋‹ค", "๊ณ ๋ž˜", "๊ณ ๋ž˜์ถœํŒ", new Date()));
        }
    
        @Override
        public List<BookDTO> selectBookList() {
            return new ArrayList<>(bookList.values());
        }
    
        @Override
        public BookDTO selectOneBook(int sequence) {
            return bookList.get(sequence);
        }
    }

1. ํ•„๋“œ(field) ์ฃผ์ž…

/* @Service : @Component์˜ ์„ธ๋ถ„ํ™” ์–ด๋…ธํ…Œ์ด์…˜์˜ ํ•œ ์ข…๋ฅ˜๋กœ Service ๊ณ„์ธต์—์„œ ์‚ฌ์šฉํ•œ๋‹ค. */
@Service("bookServiceField")
public class BookService {

    /* BookDAO ํƒ€์ž…์˜ ๋นˆ ๊ฐ์ฒด๋ฅผ ์ด ํ”„๋กœํผํ‹ฐ์— ์ž๋™์œผ๋กœ ์ฃผ์ž…ํ•ด์ค€๋‹ค. */
    @Autowired
    private BookDAO bookDAO;

		/* ๋„์„œ ๋ชฉ๋ก ์ „์ฒด ์กฐํšŒ */
    public List<BookDTO> selectAllBooks(){

        return bookDAO.selectBookList();
    }

		/* ๋„์„œ ๋ฒˆํ˜ธ๋กœ ๋„์„œ ์กฐํšŒ */
    public BookDTO searchBookBySequence(int sequence) {

        return bookDAO.selectOneBook(sequence);
    }
}

private BookDAO bookDAO = new BookDAOImpl(); ์™€ ๊ฐ™์ด ํ•„๋“œ๋ฅผ ์„ ์–ธํ•œ๋‹ค๋ฉด BookService ํด๋ž˜์Šค๋Š” BookDAOImpl ํด๋ž˜์Šค์˜ ๋ณ€๊ฒฝ์— ์ง์ ‘์ ์œผ๋กœ ์˜ํ–ฅ์„ ๋ฐ›๋Š” ๊ฐ•ํ•œ ๊ฒฐํ•ฉ์„ ๊ฐ€์ง€๊ฒŒ ๋œ๋‹ค. ๊ฐ์ฒด๊ฐ„์˜ ๊ฒฐํ•ฉ์„ ๋А์Šจํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด new BookDAOImpl() ์™€ ๊ฐ™์€ ์ง์ ‘์ ์œผ๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ƒ์„ฑ์ž ๊ตฌ๋ฌธ์„ ์ œ๊ฑฐํ•˜๊ณ  ํ•„๋“œ์— @Autowired ์–ด๋…ธํ…Œ์ด์…˜์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” BookService ๋นˆ ๊ฐ์ฒด ์ƒ์„ฑ ์‹œ BookDAO ํƒ€์ž…์˜ ๋นˆ ๊ฐ์ฒด๋ฅผ ์ฐพ์•„ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•ด์ค€๋‹ค.

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ @Repository, @Service ๋“ฑ์˜ ์–ด๋…ธํ…Œ์ด์…˜์ด ์ž‘์„ฑ ๋œ ํด๋ž˜์Šค๊ฐ€ ๋นˆ ์Šค์บ๋‹์„ ํ†ตํ•ด ์ž˜ ๋“ฑ๋ก ๋˜์—ˆ๋Š”์ง€, ๋˜ํ•œ ๊ฐ์ฒด์˜ ์˜์กด ๊ด€๊ณ„์— ๋”ฐ๋ผ @Autowired ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์˜์กด์„ฑ ์ฃผ์ž…์ด ๋˜์—ˆ๋Š”์ง€๋ฅผ ํ…Œ์ŠคํŠธํ•œ๋‹ค.

/* AnnotationConfigApplicationContext ์ƒ์„ฑ์ž์— basePackages ๋ฌธ์ž์—ด์„ ์ „๋‹ฌํ•˜๋ฉฐ ApplicationContext ์ƒ์„ฑํ•œ๋‹ค. */
ApplicationContext context = new AnnotationConfigApplicationContext("com.ohgiraffers.section01");

BookService bookService = context.getBean("bookServiceField", BookService.class);

/* ์ „์ฒด ๋„์„œ ๋ชฉ๋ก ์กฐํšŒ ํ›„ ์ถœ๋ ฅ ํ™•์ธ */
bookService.selectAllBooks().forEach(System.out::println);

/* ๋„์„œ๋ฒˆํ˜ธ๋กœ ๊ฒ€์ƒ‰ ํ›„ ์ถœ๋ ฅ ํ™•์ธ*/
System.out.println(bookService.searchBookBySequence(1));
System.out.println(bookService.searchBookBySequence(2));
  • ์‹คํ–‰ ๊ฒฐ๊ณผ
    BookDTO(sequence=1, isbn=123456, title=์ž๋ฐ”์˜ ์ •์„, author=๋‚จ๊ถ์„ฑ, publisher=๋„์šฐ์ถœํŒ, 
    	createdDate=Sun May 28 20:19:12 KST 2023)
    BookDTO(sequence=2, isbn=654321, title=์นญ์ฐฌ์€ ๊ณ ๋ž˜๋„ ์ถค์ถ”๊ฒŒ ํ•œ๋‹ค, author=๊ณ ๋ž˜, publisher=๊ณ ๋ž˜์ถœํŒ, 
    	createdDate=Sun May 28 20:19:12 KST 2023)
    BookDTO(sequence=1, isbn=123456, title=์ž๋ฐ”์˜ ์ •์„, author=๋‚จ๊ถ์„ฑ, publisher=๋„์šฐ์ถœํŒ, 
    	createdDate=Sun May 28 20:19:12 KST 2023)
    BookDTO(sequence=2, isbn=654321, title=์นญ์ฐฌ์€ ๊ณ ๋ž˜๋„ ์ถค์ถ”๊ฒŒ ํ•œ๋‹ค, author=๊ณ ๋ž˜, publisher=๊ณ ๋ž˜์ถœํŒ, 
    	createdDate=Sun May 28 20:19:12 KST 2023)

2. ์ƒ์„ฑ์ž(constoructor) ์ฃผ์ž…

/* @Service : @Component์˜ ์„ธ๋ถ„ํ™” ์–ด๋…ธํ…Œ์ด์…˜์˜ ํ•œ ์ข…๋ฅ˜๋กœ Service ๊ณ„์ธต์—์„œ ์‚ฌ์šฉํ•œ๋‹ค. */
@Service("bookServiceConstructor")
public class BookService {

    private final BookDAO bookDAO;

		/* BookDAO ํƒ€์ž…์˜ ๋นˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ์ž์— ์ž๋™์œผ๋กœ ์ฃผ์ž…ํ•ด์ค€๋‹ค. */
    @Autowired
    public BookService(BookDAO bookDAO) {
        this.bookDAO = bookDAO;
    }

    public List<BookDTO> selectAllBooks(){

        return bookDAO.selectBookList();
    }

    public BookDTO searchBookBySequence(int sequence) {

        return bookDAO.selectOneBook(sequence);
    }

}

์ƒ์„ฑ์ž์—๋„ @Autowired ์–ด๋…ธํ…Œ์ด์…˜์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” BookService ๋นˆ ๊ฐ์ฒด ์ƒ์„ฑ ์‹œ BookDAO ํƒ€์ž…์˜ ๋นˆ ๊ฐ์ฒด๋ฅผ ์ฐพ์•„ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•ด์ค€๋‹ค.

Spring 4.3 ๋ฒ„์ „ ์ดํ›„๋กœ๋Š” ์ƒ์„ฑ์ž๊ฐ€ ํ•œ ๊ฐœ ๋ฟ์ด๋ผ๋ฉด @Autowired ์–ด๋…ธํ…Œ์ด์…˜์„ ์ƒ๋žตํ•ด๋„ ์ž๋™์œผ๋กœ ์ƒ์„ฑ์ž ์ฃผ์ž…์ด ๋™์ž‘ํ•œ๋‹ค. ๋‹จ, ์ƒ์„ฑ์ž๊ฐ€ 1๊ฐœ ์ด์ƒ์ผ ๊ฒฝ์šฐ์—๋Š” ๋ช…์‹œ์ ์œผ๋กœ ์ž‘์„ฑ์„ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์œ„์˜ ์ฝ”๋“œ์— ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ์ถ”๊ฐ€๋กœ ์ž‘์„ฑํ•˜๊ณ  ๋งค๊ฐœ๋ณ€์ˆ˜ ์ƒ์„ฑ์ž์— @Autowired ์–ด๋…ธํ…Œ์ด์…˜์„ ์ƒ๋žตํ•˜๊ฒŒ ๋˜๋ฉด ์ƒ์„ฑ์ž ์ฃผ์ž…์ด ๋™์ž‘ํ•˜์ง€ ์•Š์•„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์ƒ์„ฑ์ž ์ฃผ์ž…์˜ ์žฅ์ 

  • ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ ๋  ๋•Œ ๋ชจ๋“  ์˜์กด์„ฑ์ด ์ฃผ์ž… ๋˜๋ฏ€๋กœ ์˜์กด์„ฑ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ํ•„๋“œ ์ฃผ์ž…/์„ธํ„ฐ ์ฃผ์ž…์€ ์˜์กด์„ฑ์ด ์žˆ๋Š” ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š์•„๋„ ๊ฐ์ฒด ์ƒ์„ฑ์€ ๊ฐ€๋Šฅํ•˜์—ฌ ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ ๋˜๋ฉด(๋Ÿฐํƒ€์ž„) ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
    • ์ƒ์„ฑ์ž ์ฃผ์ž…์€ ์˜์กด์„ฑ์ด ์žˆ๋Š” ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š์œผ๋ฉด ๊ฐ์ฒด ์ƒ์„ฑ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜์—ฌ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์‹œ์ ์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
  • ๊ฐ์ฒด์˜ ๋ถˆ๋ณ€์„ฑ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ํ•„๋“œ์— final ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๊ณ  ๊ฐ์ฒด ์ƒ์„ฑ ์ดํ›„ ์˜์กด์„ฑ์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์–ด ์•ˆ์ •์„ฑ์ด ๋ณด์žฅ ๋œ๋‹ค.
  • ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์ด ์ข‹๋‹ค.
    • ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ์–ด๋–ค ์˜์กด์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€ ๋ช…ํ™•ํžˆ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
  • DI ์ปจํ…Œ์ด๋„ˆ์™€์˜ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ๊ธฐ ๋•Œ๋ฌธ์— ํ…Œ์ŠคํŠธ ํ•˜๊ธฐ ์ข‹๋‹ค.
    • ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ ์—†์ด ํ…Œ์ŠคํŠธ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ @Repository, @Service ๋“ฑ์˜ ์–ด๋…ธํ…Œ์ด์…˜์ด ์ž‘์„ฑ ๋œ ํด๋ž˜์Šค๊ฐ€ ๋นˆ ์Šค์บ๋‹์„ ํ†ตํ•ด ์ž˜ ๋“ฑ๋ก ๋˜์—ˆ๋Š”์ง€, ๋˜ํ•œ ๊ฐ์ฒด์˜ ์˜์กด ๊ด€๊ณ„์— ๋”ฐ๋ผ @Autowired ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์˜์กด์„ฑ ์ฃผ์ž…์ด ๋˜์—ˆ๋Š”์ง€๋ฅผ ํ…Œ์ŠคํŠธํ•œ๋‹ค.

/* AnnotationConfigApplicationContext ์ƒ์„ฑ์ž์— basePackages ๋ฌธ์ž์—ด์„ ์ „๋‹ฌํ•˜๋ฉฐ ApplicationContext ์ƒ์„ฑํ•œ๋‹ค. */
ApplicationContext context = new AnnotationConfigApplicationContext("com.ohgiraffers.section01");

BookService bookService = context.getBean("bookServiceConstructor", BookService.class);

/* ์ „์ฒด ๋„์„œ ๋ชฉ๋ก ์กฐํšŒ ํ›„ ์ถœ๋ ฅ ํ™•์ธ */
bookService.selectAllBooks().forEach(System.out::println);

/* ๋„์„œ๋ฒˆํ˜ธ๋กœ ๊ฒ€์ƒ‰ ํ›„ ์ถœ๋ ฅ ํ™•์ธ*/
System.out.println(bookService.searchBookBySequence(1));
System.out.println(bookService.searchBookBySequence(2));
  • ์‹คํ–‰ ๊ฒฐ๊ณผ
    BookDTO(sequence=1, isbn=123456, title=์ž๋ฐ”์˜ ์ •์„, author=๋‚จ๊ถ์„ฑ, publisher=๋„์šฐ์ถœํŒ, 
    	createdDate=Sun May 28 20:19:12 KST 2023)
    BookDTO(sequence=2, isbn=654321, title=์นญ์ฐฌ์€ ๊ณ ๋ž˜๋„ ์ถค์ถ”๊ฒŒ ํ•œ๋‹ค, author=๊ณ ๋ž˜, publisher=๊ณ ๋ž˜์ถœํŒ, 
    	createdDate=Sun May 28 20:19:12 KST 2023)
    BookDTO(sequence=1, isbn=123456, title=์ž๋ฐ”์˜ ์ •์„, author=๋‚จ๊ถ์„ฑ, publisher=๋„์šฐ์ถœํŒ, 
    	createdDate=Sun May 28 20:19:12 KST 2023)
    BookDTO(sequence=2, isbn=654321, title=์นญ์ฐฌ์€ ๊ณ ๋ž˜๋„ ์ถค์ถ”๊ฒŒ ํ•œ๋‹ค, author=๊ณ ๋ž˜, publisher=๊ณ ๋ž˜์ถœํŒ, 
    	createdDate=Sun May 28 20:19:12 KST 2023)

3. ์„ธํ„ฐ(setter) ์ฃผ์ž…

/* @Service : @Component์˜ ์„ธ๋ถ„ํ™” ์–ด๋…ธํ…Œ์ด์…˜์˜ ํ•œ ์ข…๋ฅ˜๋กœ Service ๊ณ„์ธต์—์„œ ์‚ฌ์šฉํ•œ๋‹ค. */
@Service("bookServiceSetter")
public class BookService {

    private BookDAO bookDAO;

    /* BookDAO ํƒ€์ž…์˜ ๋นˆ ๊ฐ์ฒด๋ฅผ setter์— ์ž๋™์œผ๋กœ ์ฃผ์ž…ํ•ด์ค€๋‹ค. */
    @Autowired
    public void setBookDAO(BookDAO bookDAO) {
        this.bookDAO = bookDAO;
    }

    public List<BookDTO> selectAllBooks(){

        return bookDAO.selectBookList();
    }

    public BookDTO searchBookBySequence(int sequence) {

        return bookDAO.selectOneBook(sequence);
    }
}

setter ๋ฉ”์†Œ๋“œ์—๋„ @Autowired ์–ด๋…ธํ…Œ์ด์…˜์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” BookService ๋นˆ ๊ฐ์ฒด ์ƒ์„ฑ ์‹œ BookDAO ํƒ€์ž…์˜ ๋นˆ ๊ฐ์ฒด๋ฅผ ์ฐพ์•„ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•ด์ค€๋‹ค.

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ @Repository, @Service ๋“ฑ์˜ ์–ด๋…ธํ…Œ์ด์…˜์ด ์ž‘์„ฑ ๋œ ํด๋ž˜์Šค๊ฐ€ ๋นˆ ์Šค์บ๋‹์„ ํ†ตํ•ด ์ž˜ ๋“ฑ๋ก ๋˜์—ˆ๋Š”์ง€, ๋˜ํ•œ ๊ฐ์ฒด์˜ ์˜์กด ๊ด€๊ณ„์— ๋”ฐ๋ผ @Autowired ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์˜์กด์„ฑ ์ฃผ์ž…์ด ๋˜์—ˆ๋Š”์ง€๋ฅผ ํ…Œ์ŠคํŠธํ•œ๋‹ค.

/* AnnotationConfigApplicationContext ์ƒ์„ฑ์ž์— basePackages ๋ฌธ์ž์—ด์„ ์ „๋‹ฌํ•˜๋ฉฐ ApplicationContext ์ƒ์„ฑํ•œ๋‹ค. */
ApplicationContext context = new AnnotationConfigApplicationContext("com.ohgiraffers.section01");

BookService bookService = context.getBean("bookServiceSetter", BookService.class);

/* ์ „์ฒด ๋„์„œ ๋ชฉ๋ก ์กฐํšŒ ํ›„ ์ถœ๋ ฅ ํ™•์ธ */
bookService.selectAllBooks().forEach(System.out::println);

/* ๋„์„œ๋ฒˆํ˜ธ๋กœ ๊ฒ€์ƒ‰ ํ›„ ์ถœ๋ ฅ ํ™•์ธ*/
System.out.println(bookService.searchBookBySequence(1));
System.out.println(bookService.searchBookBySequence(2));
  • ์‹คํ–‰ ๊ฒฐ๊ณผ
    BookDTO(sequence=1, isbn=123456, title=์ž๋ฐ”์˜ ์ •์„, author=๋‚จ๊ถ์„ฑ, publisher=๋„์šฐ์ถœํŒ, 
    	createdDate=Sun May 28 20:19:12 KST 2023)
    BookDTO(sequence=2, isbn=654321, title=์นญ์ฐฌ์€ ๊ณ ๋ž˜๋„ ์ถค์ถ”๊ฒŒ ํ•œ๋‹ค, author=๊ณ ๋ž˜, publisher=๊ณ ๋ž˜์ถœํŒ, 
    	createdDate=Sun May 28 20:19:12 KST 2023)
    BookDTO(sequence=1, isbn=123456, title=์ž๋ฐ”์˜ ์ •์„, author=๋‚จ๊ถ์„ฑ, publisher=๋„์šฐ์ถœํŒ, 
    	createdDate=Sun May 28 20:19:12 KST 2023)
    BookDTO(sequence=2, isbn=654321, title=์นญ์ฐฌ์€ ๊ณ ๋ž˜๋„ ์ถค์ถ”๊ฒŒ ํ•œ๋‹ค, author=๊ณ ๋ž˜, publisher=๊ณ ๋ž˜์ถœํŒ, 
    	createdDate=Sun May 28 20:19:12 KST 2023)

2. ๋” ๋งŽ์€ DI Annotation

@Autowired ์–ด๋…ธํ…Œ์ด์…˜์€ ๊ฐ€์žฅ ๋ณดํŽธ์ ์œผ๋กœ ์‚ฌ์šฉ ๋˜๋Š” ์˜์กด์„ฑ ์ฃผ์ž… Annotation์ด๋‹ค. @Autowired ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ๋˜๋Š” ๋Œ€์ฒดํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์–ด๋…ธํ…Œ์ด์…˜์„ ํ•™์Šตํ•œ๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ๋Š” ํ…Œ์ŠคํŠธ์— ๊ณตํ†ต์ ์œผ๋กœ ์‚ฌ์šฉ ํ•  Pokemon, Charmander, Pikachu, Squirtle ํด๋ž˜์Šค์ด๋‹ค.

  1. Pokemon

    public interface Pokemon {
    	
    	/* ๊ณต๊ฒฉํ•˜๋‹ค */
    	void attack();
    }
  2. Charmander

    @Component
    public class Charmander implements Pokemon {
    
    	@Override
    	public void attack() {
    		System.out.println("ํŒŒ์ด๋ฆฌ ๋ถˆ๊ฝƒ ๊ณต๊ฒฉ๐Ÿ”ฅ");
    	}
    }
  3. Pikachu

    @Component
    public class Pikachu implements Pokemon {
    
    	@Override
    	public void attack() {
    		System.out.println("ํ”ผ์นด์ธ„ ๋ฐฑ๋งŒ๋ณผํŠธโšก");
    	}
    }
  4. Squirtle

    @Component
    public class Squirtle implements Pokemon {
    
    	@Override
    	public void attack() {
    		System.out.println("๊ผฌ๋ถ€๊ธฐ ๋ฌผ๋Œ€ํฌ ๋ฐœ์‚ฌ๐ŸŒŠ");
    	}
    }

1. @Primary

๐Ÿ’ก @Primary ์–ด๋…ธํ…Œ์ด์…˜์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋นˆ ๊ฐ์ฒด ์ค‘์—์„œ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๊ฐ€์žฅ ๋†’์€ ๋นˆ ๊ฐ์ฒด๋ฅผ ์ง€์ •ํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค.

์ƒ์„ฑ์ž๋กœ Pokemon ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ์˜์กด์„ฑ ์ฃผ์ž… ๋ฐ›๋Š” PokemonService ํด๋ž˜์Šค๋ฅผ ์„ ์–ธํ•œ๋‹ค.

@Service("pokemonServicePrimary")
public class PokemonService {
	
	private Pokemon pokemon;
	
	@Autowired
	public PokemonService(Pokemon pokemon) {
		this.pokemon = pokemon;
	}
	
	public void pokemonAttack() {
		pokemon.attack();
	}

}

Charmander, Pikachu, Squirtle, PokemonService ๋ฅผ ๋นˆ ์Šค์บ๋‹ ํ•  ์ˆ˜ ์žˆ๋Š” basePackages๋ฅผ ์„ค์ •ํ•˜์—ฌ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

ApplicationContext context = new AnnotationConfigApplicationContext("com.ohgiraffers.section02");

PokemonService pokemonService = context.getBean("pokemonServicePrimary", PokemonService.class);
		
pokemonService.pokemonAttack();
  • ์‹คํ–‰ ๊ฒฐ๊ณผ
    Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: 
    Error creating bean with name 'pokemonServicePrimary' defined in file ํŒŒ์ผ ๊ฒฝ๋กœ : 
    Unsatisfied dependency expressed through constructor parameter 0; 
    nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
    No qualifying bean of type 'com.ohgiraffers.section02.common.Pokemon' available: 
    expected single matching bean but found 3: charmander,pikachu,squirtle
    ...์ƒ๋žต

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์— Pokemon ํƒ€์ž…์˜ ๋นˆ ๊ฐ์ฒด๊ฐ€ charmander,pikachu,squirtle 3๊ฐœ๊ฐ€ ์žˆ์–ด 1๊ฐœ์˜ ๊ฐ์ฒด๋ฅผ PokemonService์˜ ์ƒ์„ฑ์ž๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์—†์–ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

Charmander, Pikachu, Squirtle ์ค‘์—์„œ Charmander ๋นˆ ๊ฐ์ฒด๋ฅผ ์šฐ์„ ์ ์œผ๋กœ ์ฃผ์ž…๋ฐ›๋„๋ก @Primary ์–ด๋…ธํ…Œ์ด์…˜์„ ์„ค์ •ํ•œ๋‹ค.

@Component
@Primary
public class Charmander implements Pokemon {

    @Override
    public void attack() {
        System.out.println("ํŒŒ์ด๋ฆฌ ๋ถˆ๊ฝƒ ๊ณต๊ฒฉ๐Ÿ”ฅ");
    }
}

@Primary ์–ด๋…ธํ…Œ์ด์…˜์„ ์„ค์ •ํ•˜๋ฉด @Autowired๋กœ ๋™์ผํ•œ ํƒ€์ž…์˜ ์—ฌ๋Ÿฌ ๋นˆ์„ ์ฐพ๊ฒŒ ๋˜๋Š” ๊ฒฝ์šฐ ์ž๋™์œผ๋กœ ์—ฐ๊ฒฐ ์šฐ์„  ์‹œ ํ•  ํƒ€์ž…์œผ๋กœ ์„ค์ • ๋œ๋‹ค.

๋™์ผํ•œ ํƒ€์ž…์˜ ํด๋ž˜์Šค ์ค‘ ํ•œ ๊ฐœ๋งŒ @Primary ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

Charmander ๋นˆ ๊ฐ์ฒด์— @Primary ์–ด๋…ธํ…Œ์ด์…˜์ด ์„ค์ •๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ, PokemonService์˜ ์ƒ์„ฑ์ž๋กœ Pokemon ๊ฐ์ฒด๋ฅผ ์ฃผ์ž…๋ฐ›์œผ๋ฉด Charmander ๋นˆ ๊ฐ์ฒด๊ฐ€ ์šฐ์„ ์ ์œผ๋กœ ์ฃผ์ž…๋œ๋‹ค.

  • ์‹คํ–‰ ๊ฒฐ๊ณผ
    ํŒŒ์ด๋ฆฌ ๋ถˆ๊ฝƒ ๊ณต๊ฒฉ๐Ÿ”ฅ

2. @Qualifier

๐Ÿ’ก @Qualifier ์–ด๋…ธํ…Œ์ด์…˜์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋นˆ ๊ฐ์ฒด ์ค‘์—์„œ ํŠน์ • ๋นˆ ๊ฐ์ฒด๋ฅผ ์ด๋ฆ„์œผ๋กœ ์ง€์ •ํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค.

2-1. ํ•„๋“œ ์ฃผ์ž…

ํ•„๋“œ๋กœ Pokemon ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ์˜์กด์„ฑ ์ฃผ์ž… ๋ฐ›๋Š” PokemonService ํด๋ž˜์Šค๋ฅผ ์„ ์–ธํ•œ๋‹ค. @Autowired ์–ด๋…ธํ…Œ์ด์…˜๊ณผ ํ•จ๊ป˜ @Qualifier ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๋นˆ ์ด๋ฆ„์„ ํ†ตํ•ด ์ฃผ์ž…ํ•  ๋นˆ ๊ฐ์ฒด๋ฅผ ์ง€์ •ํ•œ๋‹ค.

@Service("pokemonServiceQualifier")
public class PokemonService {
	
  /* @Qualifier ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ pikachu ๋นˆ ๊ฐ์ฒด๋ฅผ ์ง€์ •ํ•œ๋‹ค. */
	@Autowired
	@Qualifier("pikachu")
	private Pokemon pokemon;
	
	public void pokemonAttack() {
		pokemon.attack();
	
}

Charmander, Pikachu, Squirtle, PokemonService ๋ฅผ ๋นˆ ์Šค์บ๋‹ ํ•  ์ˆ˜ ์žˆ๋Š” basePackages๋ฅผ ์„ค์ •ํ•˜์—ฌ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

ApplicationContext context = new AnnotationConfigApplicationContext("com.ohgiraffers.section02");

PokemonService pokemonService = context.getBean("pokemonServiceQualifier", PokemonService.class);
		
pokemonService.pokemonAttack();
  • ์‹คํ–‰ ๊ฒฐ๊ณผ
    ํ”ผ์นด์ธ„ ๋ฐฑ๋งŒ๋ณผํŠธโšก

@Primary ์–ด๋…ธํ…Œ์ด์…˜๊ณผ @Qualifier ์–ด๋…ธํ…Œ์ด์…˜์ด ํ•จ๊ป˜ ์“ฐ์˜€์„ ๋•Œ @Qualifier ๊ฐ€ ์šฐ์„ ํ•œ๋‹ค๋Š” ๊ฒƒ๋„ ๊ฒฐ๊ณผ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

2-2. ์ƒ์„ฑ์ž ์ฃผ์ž…

์ƒ์„ฑ์ž ์ฃผ์ž…์˜ ๊ฒฝ์šฐ @Qualifier ์–ด๋…ธํ…Œ์ด์…˜์€ ๋ฉ”์†Œ๋“œ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ ์•ž์— ๊ธฐ์žฌํ•œ๋‹ค. ์—ญ์‹œ ๋นˆ ์ด๋ฆ„์„ ํ†ตํ•ด ์ฃผ์ž…ํ•  ๋นˆ ๊ฐ์ฒด๋ฅผ ์ง€์ •ํ•œ๋‹ค.

@Service("pokemonServiceQualifier")
public class PokemonService {
	
	private Pokemon pokemon;

  /* @Qualifier ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ squirtle ๋นˆ ๊ฐ์ฒด๋ฅผ ์ง€์ •ํ•œ๋‹ค. */
	@Autowired
	public PokemonService(@Qualifier("squirtle") Pokemon pokemon) {
		this.pokemon = pokemon;
	}
	
	public void pokemonAttack() {
		pokemon.attack();
	}
}
  • ์‹คํ–‰ ๊ฒฐ๊ณผ
    ๊ผฌ๋ถ€๊ธฐ ๋ฌผ๋Œ€ํฌ ๋ฐœ์‚ฌ๐ŸŒŠ

3. Collection

๊ฐ™์€ ํƒ€์ž…์˜ ๋นˆ์„ ์—ฌ๋Ÿฌ ๊ฐœ ์ฃผ์ž… ๋ฐ›๊ณ  ์‹ถ๋‹ค๋ฉด Collection ํƒ€์ž…์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

3-1. List ํƒ€์ž…

List<Pokemon> ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ์˜์กด์„ฑ ์ฃผ์ž… ๋ฐ›๋Š” PokemonService ํด๋ž˜์Šค๋ฅผ ์„ ์–ธํ•œ๋‹ค.

@Service("pokemonServiceCollection")
public class PokemonService {
	
	/* 1. List ํƒ€์ž…์œผ๋กœ ์ฃผ์ž… */
	private List<Pokemon> pokemonList;

	@Autowired
	public PokemonService(List<Pokemon> pokemonList) {
		this.pokemonList = pokemonList;
	}

	public void pokemonAttack() {
		pokemonList.forEach(Pokemon::attack);
	}
}

Charmander, Pikachu, Squirtle, PokemonService ๋ฅผ ๋นˆ ์Šค์บ๋‹ ํ•  ์ˆ˜ ์žˆ๋Š” basePackages๋ฅผ ์„ค์ •ํ•˜์—ฌ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

ApplicationContext context = new AnnotationConfigApplicationContext("com.ohgiraffers.section02");

PokemonService pokemonService = context.getBean("pokemonServiceCollection", PokemonService.class);
		
pokemonService.pokemonAttack();
  • ์‹คํ–‰ ๊ฒฐ๊ณผ
    ํŒŒ์ด๋ฆฌ ๋ถˆ๊ฝƒ ๊ณต๊ฒฉ๐Ÿ”ฅ
    ํ”ผ์นด์ธ„ ๋ฐฑ๋งŒ๋ณผํŠธโšก
    ๊ผฌ๋ถ€๊ธฐ ๋ฌผ๋Œ€ํฌ ๋ฐœ์‚ฌ๐ŸŒŠ
    bean ์ด๋ฆ„์˜ ์‚ฌ์ „์ˆœ์œผ๋กœ List์— ์ถ”๊ฐ€ ๋˜์–ด ๋ชจ๋“  Pokemon ํƒ€์ž…์˜ ๋นˆ์ด ์ฃผ์ž… ๋œ๋‹ค.

3-2. Map ํƒ€์ž…

๋˜๋Š” Map<String, Pokemon> ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ์˜์กด์„ฑ ์ฃผ์ž… ๋ฐ›๋Š” PokemonService ํด๋ž˜์Šค๋ฅผ ์„ ์–ธํ•œ๋‹ค.

@Service("pokemonServiceCollection")
public class PokemonService {
	
	/* 2. Map ํƒ€์ž…์œผ๋กœ ์ฃผ์ž… */
	private Map<String, Pokemon> pokemonMap;
	
	@Autowired
	public PokemonService(Map<String, Pokemon> pokemonMap) {
		this.pokemonMap = pokemonMap;
	}
	
	public void pokemonAttack() {
      pokemonMap.forEach((k, v) -> {
          System.out.println("key : " + k);
          System.out.print("๊ณต๊ฒฉ : ");
          v.attack();
      });
  }
}
  • ์‹คํ–‰ ๊ฒฐ๊ณผ
    key : charmander
    ๊ณต๊ฒฉ : ํŒŒ์ด๋ฆฌ ๋ถˆ๊ฝƒ ๊ณต๊ฒฉ๐Ÿ”ฅ
    key : pikachu
    ๊ณต๊ฒฉ : ํ”ผ์นด์ธ„ ๋ฐฑ๋งŒ๋ณผํŠธโšก
    key : squirtle
    ๊ณต๊ฒฉ : ๊ผฌ๋ถ€๊ธฐ ๋ฌผ๋Œ€ํฌ ๋ฐœ์‚ฌ๐ŸŒŠ
    bean ์ด๋ฆ„์˜ ์‚ฌ์ „์ˆœ์œผ๋กœ Map์— ์ถ”๊ฐ€ ๋˜์–ด ๋ชจ๋“  Pokemon ํƒ€์ž…์˜ ๋นˆ์ด ์ฃผ์ž… ๋œ๋‹ค.

4. @Resource

๐Ÿ’ก @Resource ์–ด๋…ธํ…Œ์ด์…˜์€ ์ž๋ฐ”์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค. @Autowired์™€ ๊ฐ™์€ ์Šคํ”„๋ง ์–ด๋…ธํ…Œ์ด์…˜๊ณผ ๋‹ค๋ฅด๊ฒŒ name ์†์„ฑ ๊ฐ’์œผ๋กœ ์˜์กด์„ฑ ์ฃผ์ž…์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์€ ์‚ฌ์šฉํ•˜๊ธฐ ์ „ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์˜์กด์„ฑ ์ถ”๊ฐ€๊ฐ€ ํ•„์š”ํ•˜๋ฏ€๋กœ Maven Repository์—์„œ javax annoataion์„ ๊ฒ€์ƒ‰ํ•˜์—ฌ build.gradle.kts ํŒŒ์ผ์— ์•„๋ž˜์™€ ๊ฐ™์€ ๊ตฌ๋ฌธ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

dependencies {
	implementation("javax.annotation:javax.annotation-api:1.3.2")
	...์ƒ๋žต
}

4-1. ์ด๋ฆ„์œผ๋กœ ์ฃผ์ž…

ํ•„๋“œ๋กœ Pokemon ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ์˜์กด์„ฑ ์ฃผ์ž… ๋ฐ›๋Š” PokemonService ํด๋ž˜์Šค๋ฅผ ์„ ์–ธํ•œ๋‹ค. @Resource ์–ด๋…ธํ…Œ์ด์…˜์˜ name ์†์„ฑ์— ์ฃผ์ž…ํ•  ๋นˆ ๊ฐ์ฒด์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•œ๋‹ค.

@Service("pokemonServiceResource")
public class PokemonService {
  
  /* pikachu ์ด๋ฆ„์˜ ๋นˆ ์ง€์ • */
	@Resource(name = "pikachu")
	private Pokemon pokemon;

	public void pokemonAttack() {
		pokemon.attack();
	}
}

Charmander, Pikachu, Squirtle, PokemonService ๋ฅผ ๋นˆ ์Šค์บ๋‹ ํ•  ์ˆ˜ ์žˆ๋Š” basePackages๋ฅผ ์„ค์ •ํ•˜์—ฌ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

ApplicationContext context = new AnnotationConfigApplicationContext("com.ohgiraffers.section02");

PokemonService pokemonService = context.getBean("pokemonServiceResour", PokemonService.class);
		
pokemonService.pokemonAttack();
  • ์‹คํ–‰ ๊ฒฐ๊ณผ
    ํ”ผ์นด์ธ„ ๋ฐฑ๋งŒ๋ณผํŠธโšก

4-2. ํƒ€์ž…์œผ๋กœ ์ฃผ์ž…

List<Pokemon> ํƒ€์ž…์œผ๋กœ ๋ณ€๊ฒฝํ•œ ๋’ค name ์†์„ฑ์„ ๋”ฐ๋กœ ๊ธฐ์žฌํ•˜์ง€ ์•Š๊ณ  ๋™์ž‘์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” name ์†์„ฑ์„ ํ†ตํ•ด ์ฃผ์ž…ํ•˜์ง€๋งŒ name ์†์„ฑ์ด ์—†์„ ๊ฒฝ์šฐ Type์„ ํ†ตํ•ด ์˜์กด์„ฑ ์ฃผ์ž…ํ•œ๋‹ค.

@Service("pokemonServiceResource")
public class PokemonService {
  
  @Resource
	private List<Pokemon> pokemonList;

	public void pokemonAttack() {
		pokemonList.forEach(Pokemon::attack);
	}
}
  • ์‹คํ–‰ ๊ฒฐ๊ณผ
    ํŒŒ์ด๋ฆฌ ๋ถˆ๊ฝƒ ๊ณต๊ฒฉ๐Ÿ”ฅ
    ํ”ผ์นด์ธ„ ๋ฐฑ๋งŒ๋ณผํŠธโšก
    ๊ผฌ๋ถ€๊ธฐ ๋ฌผ๋Œ€ํฌ ๋ฐœ์‚ฌ๐ŸŒŠ
    bean ์ด๋ฆ„์˜ ์‚ฌ์ „์ˆœ์œผ๋กœ List์— ์ถ”๊ฐ€ ๋˜์–ด ๋ชจ๋“  Pokemon ํƒ€์ž…์˜ ๋นˆ์ด ์ฃผ์ž… ๋œ๋‹ค.

์‚ฌ์šฉ ์‹œ ์œ ์˜ํ•  ์ ์€ ํ•„๋“œ ์ฃผ์ž… ๊ณผ ์„ธํ„ฐ ์ฃผ์ž… ์€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์ƒ์„ฑ์ž ์ฃผ์ž… ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์ ์ด๋‹ค.

5. @Inject

๐Ÿ’ก `@Inject` ์–ด๋…ธํ…Œ์ด์…˜์€ ์ž๋ฐ”์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค. `@Autowired` ์–ด๋…ธํ…Œ์ด์…˜๊ณผ ๊ฐ™์ด `Type` ์œผ๋กœ ๋นˆ์„ ์˜์กด์„ฑ ์ฃผ์ž…ํ•œ๋‹ค.

ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์€ ์‚ฌ์šฉํ•˜๊ธฐ ์ „ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์˜์กด์„ฑ ์ถ”๊ฐ€๊ฐ€ ํ•„์š”ํ•˜๋ฏ€๋กœ Maven Repository์—์„œ javax inject์„ ๊ฒ€์ƒ‰ํ•˜์—ฌ build.gradle.kts ํŒŒ์ผ์— ์•„๋ž˜์™€ ๊ฐ™์€ ๊ตฌ๋ฌธ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

dependencies {
	implementation("javax.inject:javax.inject:1")
	...์ƒ๋žต
}

5-1. ํ•„๋“œ ์ฃผ์ž…

ํ•„๋“œ๋กœ Pokemon ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ์˜์กด์„ฑ ์ฃผ์ž… ๋ฐ›๋Š” PokemonService ํด๋ž˜์Šค๋ฅผ ์„ ์–ธํ•œ๋‹ค. @Inject ์–ด๋…ธํ…Œ์ด์…˜์€ Type ์œผ๋กœ ์˜์กด์„ฑ ์ฃผ์ž…ํ•˜๋ฏ€๋กœ 3๊ฐœ์˜ ๋™์ผํ•œ ํƒ€์ž…์˜ ๋นˆ์ด ์žˆ๋Š” ํ˜„์žฌ ์ƒํ™ฉ์—์„œ๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๋”ฐ๋ผ์„œ @Named ์–ด๋…ธํ…Œ์ด์…˜์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด์„œ ๋นˆ์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋ฉด ํ•ด๋‹น ๋นˆ์„ ์˜์กด์„ฑ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค.

@Service("pokemonServiceInject")
public class PokemonService {

	/* 1. ํ•„๋“œ ์ฃผ์ž… */
	@Inject
	@Named("pikachu")
	private Pokemon pokemon;

	public void pokemonAttack() {
		pokemon.attack();
	}
}

Charmander, Pikachu, Squirtle, PokemonService ๋ฅผ ๋นˆ ์Šค์บ๋‹ ํ•  ์ˆ˜ ์žˆ๋Š” basePackages๋ฅผ ์„ค์ •ํ•˜์—ฌ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

ApplicationContext context = new AnnotationConfigApplicationContext("com.ohgiraffers.section02");

PokemonService pokemonService = context.getBean("pokemonServiceInject", PokemonService.class);
		
pokemonService.pokemonAttack();
  • ์‹คํ–‰ ๊ฒฐ๊ณผ
    ํ”ผ์นด์ธ„ ๋ฐฑ๋งŒ๋ณผํŠธโšก

5-2. ์ƒ์„ฑ์ž ์ฃผ์ž…

์ƒ์„ฑ์ž๋กœ Pokemon ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ์˜์กด์„ฑ ์ฃผ์ž… ๋ฐ›๋Š” PokemonService ํด๋ž˜์Šค๋ฅผ ์„ ์–ธํ•œ๋‹ค.

@Service("pokemonServiceInject")
public class PokemonService {

	private Pokemon pokemon;

	/* 2. ์ƒ์„ฑ์ž ์ฃผ์ž… */
	@Inject
	public PokemonService(@Named("pikachu") Pokemon pokemon) {
		this.pokemon = pokemon;
	}

	public void pokemonAttack() {
		pokemon.attack();
	}
}

@Named ์–ด๋…ธํ…Œ์ด์…˜์˜ ๊ฒฝ์šฐ ๋ฉ”์†Œ๋“œ ๋ ˆ๋ฒจ, ํŒŒ๋ผ๋ฏธํ„ฐ ๋ ˆ๋ฒจ์—์„œ ๋‘˜ ๋‹ค ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

  • ์‹คํ–‰ ๊ฒฐ๊ณผ
    ํ”ผ์นด์ธ„ ๋ฐฑ๋งŒ๋ณผํŠธโšก

5-3. ์„ธํ„ฐ ์ฃผ์ž…

์„ธํ„ฐ๋กœ Pokemon ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ์˜์กด์„ฑ ์ฃผ์ž… ๋ฐ›๋Š” PokemonService ํด๋ž˜์Šค๋ฅผ ์„ ์–ธํ•œ๋‹ค.

@Service("pokemonServiceInject")
public class PokemonService {

	private Pokemon pokemon;

	/* 3. ์„ธํ„ฐ ์ฃผ์ž… */
	@Inject
	public void setPokemon(@Named("pikachu") Pokemon pokemon) {
		this.pokemon = pokemon;
	}

	public void pokemonAttack() {
		pokemon.attack();
	}
}
  • ์‹คํ–‰ ๊ฒฐ๊ณผ
    ํ”ผ์นด์ธ„ ๋ฐฑ๋งŒ๋ณผํŠธโšก

@Inject๋Š” ํ•„๋“œ ์ฃผ์ž…, ์ƒ์„ฑ์ž ์ฃผ์ž…, ์„ธํ„ฐ ์ฃผ์ž… ์ด ๋ชจ๋‘ ๊ฐ€๋Šฅํ•˜๋‹ค.

์ •๋ฆฌ

DI๋Š” ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๋งค์šฐ ์ค‘์š”ํ•œ ๊ฐœ๋… ์ค‘ ํ•˜๋‚˜๋กœ, ๊ฐœ๋ฐœ์ž๋Š” ๊ฐ์ฒด ๊ฐ„์˜ ์˜์กด์„ฑ์„ ์ง์ ‘ ๊ด€๋ฆฌํ•˜์ง€ ์•Š๊ณ  ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๊ฐ์ฒด ๊ฐ„์˜ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•ด์ฃผ๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์–‘ํ•œ DI ์–ด๋…ธํ…Œ์ด์…˜์ด ์žˆ๋Š”๋ฐ ๊ฐ๊ฐ์˜ ํŠน์ง•๊ณผ ์‚ฌ์šฉ ๋ฐฉ์‹์ด ๋‹ค๋ฅด๋‹ค.

@Autowried@Resource@Inject
์ œ๊ณตSpringJavaJava
์ง€์› ๋ฐฉ์‹ํ•„๋“œ, ์ƒ์„ฑ์ž, ์„ธํ„ฐํ•„๋“œ, ์„ธํ„ฐํ•„๋“œ, ์ƒ์„ฑ์ž, ์„ธํ„ฐ
๋นˆ ๊ฒ€์ƒ‰ ์šฐ์„  ์ˆœ์œ„ํƒ€์ž… โ†’ ์ด๋ฆ„์ด๋ฆ„ โ†’ ํƒ€์ž…ํƒ€์ž… โ†’ ์ด๋ฆ„
๋นˆ ์ง€์ • ๋ฌธ๋ฒ•@Autowired
@Qualifier(โ€nameโ€)@Resource(name=โ€nameโ€)@Inject
@Named(โ€nameโ€)
profile
๋‚˜๋Š” ํ•  ์ˆ˜ ์žˆ๋‹ค...!

0๊ฐœ์˜ ๋Œ“๊ธ€