Tiny Bunny
본문 바로가기
⚙️Backend/SPRING

[Spring Boot] 스프링 의존성 주입 @Autowired, @Resource, @Inject

by soonybutter 2024. 12. 14.
728x90

 

 

스프링 의존성 주입 @Autowired, @Resource, @Inject (Java Spring Dependency Injection)

의존성 주입은 객체를 직접 생성하지 않고 @Service을 이용하여 class annotation으로 달아주면 스프링은 beanFactory에 담아 두고 사용하는 곳에 @Autowired을 사용하는 곳에 해당 bean을 찾아 주입시켜 객체를 사용할 수 있게 도와준다.

1. @Autowired

@Autowired 주입하려고 하는 객체의 타입이 일치하는 객체를 loc 컨테이너 안에 존재하는 Bean을 자동으로 주입한다.

주입 방법은 3가지가 있다.

필드 주입 (Field Injection)

필드에 @Autowired 어노테이션을 붙여 주면 자동으로 의존성이 주입된다. 매우 간단하며 예제로 많이 사용되는 방법이다.

public class TestController { @Autowired private InjectSampleService injectSampleService; @GetMapping("/persion") public List<Person> getPersions(@RequestParam(name = "name") String name) { return injectSampleService.query(name); } }

생성자 주입 (Constructor Injection)

단일 생성자인 경우 @Autowired 어노테이션을 붙이지 않아도 되지만 생성자 2개 이상일 경우에는 어노테이션을 꼭 붙여주어야 한다.

public class TestController { private InjectSampleService injectSampleService; @Autowired // spring 4.3 버전 이상부터는 생략 가능 public TestController(InjectSampleService injectSampleService) { this.injectSampleService= injectSampleService; } @GetMapping("/persion") public List<Person> getPersions(@RequestParam(name = "name") String name) { return injectSampleService.query(name); } }

세터 주입 (Setter Injection)

메서드 이름이 세터 네이밍 패턴(setXXXX)이 아니어도 동일한 기능을 하지만 일관성과 명확한 코드를 만들기 위해서

정확한 이름을 사용하는 것을 추천한다.

public class TestController { private InjectSampleService injectSampleService; @Autowired // spring 4.3 버전 이상부터는 생략 가능 public void setInjectSampleService(InjectSampleService injectSampleService) { this.injectSampleService= injectSampleService; } }
 

여기서 알아야 할 내용은 필드 주입을 사용하면 다음과 같이 경고가 발생한다.

Spring Team recommends: “Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies”.

필드 주입을 사용하지 말고 생성자 주입을 사용하라는데 생성자 주입을 권장하는 이유는 다음과 같다.

https://madplay.github.io/post/why-constructor-injection-is-better-than-field-injection

- 순환 참조 방지 (A가 B를 참조하고 B가 A를 참조할 때 발생될 수 있는 문제)

- 테스트에 용이

- final 선언 가능

- 오류 방지 (불변(immutable) 객체 또는 null 방지 가능)

Qualifier 어노테이션

동일한 타입의 빈 객체가 여러개 정의되어 있을 경우,

우선적으로 사용할 빈 책체의 <bean> 태그 하위에 <qualifier>태그를 설정하여 특정 빈을 주입할 수 있게 한다.

<bean id="testInject1" class="com.example.demo.services" > <qualifier value="qualifierTest"/> </bean> <bean id="testInject2" class="com.example.demo.services" />
public class WordRegisterServiceUseAutowired { @Autowired @Qualifier("qualifierTest") private InjectSampleService injectSampleService; @GetMapping("/persion") public List<Person> getPersions(@RequestParam(name = "name") String name) { return injectSampleService.query(name); } }

2. @Resource

@Resource는 주입하려고 하는 객체의 이름(id)이 일치하는 객체를 자동으로 주입하며 필드, Setter에 붙일 수 있지만 생성자에는 붙일 수 없다. @Autowired와 마찬가지로 반드시 기본 생성자가 정의되어 있어야 한다.

 

의존성 설정

프로젝트에서 사용하기 위해 javax.annotation-api 의존성을 추가한다.

<dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.2</version> </dependency>

 

필드 주입 (Field Injection)

import javax.annotation.Resource; public class WordRegisterServiceUseResource { @Resource private WordDao wordDao; public WordRegisterServiceUseResource() { } }

 

세터 주입 (Setter Injection)

import javax.annotation.Resource; public class WordRegisterServiceUseResource { private WordDao wordDao; public WordRegisterServiceUseResource() { } @Resource public WordRegisterServiceUseResource(WordDao wordDao) { this.wordDao = wordDao; } }
 

3. @Inject

@Inject는 @Autowired와 유사하게 주입하려고 하는 객체의 타입이 일치하는 객체를 자동으로 주입한다.

 

의존성 설정

프로젝트에서 사용하기 위해 javax.inject 의존성을 추가한다.

<dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency>

필드 주입 (Field Injection)

import javax.inject.Inject; public class WordRegisterServiceUseAutowired { @Inject private WordDao wordDao; public WordRegisterServiceUseAutowired() { } }

 

생성자 주입 (Constructor Injection)

import javax.inject.Inject; public class WordRegisterServiceUseAutowired { private WordDao wordDao; @Inject public WordRegisterServiceUseAutowired(WordDao wordDao) { this.wordDao = wordDao; } }

 

세터 주입 (Setter Injection)

import javax.inject.Inject; public class WordRegisterServiceUseAutowired { private WordDao wordDao; public WordRegisterServiceUseAutowired() { } @Inject public void setWordDao(WordDao wordDao) { this.wordDao = wordDao; } }

 

Named 어노테이션

@Autowired의 @Qualifier 와 비슷한 역할을 하는게 @Inject에서의 @Named이다.

@Qualifier와 달리 @Named에는 bean id 을 지정하므로

@Autowired, @Qualifier를 사용할때에 비해 XML 설정 파일이 다소 짧아진다는 특징이 있다.

 

XML 설정 파일

<Qualifier> 태그가 필요한 @Qualifier와 달리 @Named는 XML 설정 파일에 추가적으로 설정할 것이 없다.

<bean id="wordDao1" class="com.word.dao.WordDao"/> <bean id="wordDao2" class="com.word.dao.WordDao"/> <bean id="wordDao3" class="com.word.dao.WordDao"/>

 

자바 코드

@Named에 빈 이름(id)를 지정한다.

import javax.inject.Inject; import javax.inject.Named; public class WordRegisterServiceUseInject { @Inject @Named("wordDao1") private WordDao wordDao; public WordRegisterServiceUseInject() { } }

 

 

 

*공부용 기록입니다.

728x90

TOP

Designed by 티스토리