์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
- ์ฟ ๋ฒ๋คํฐ์ค
- db์ํคํ ์ณ
- ๋์์ธํจํด
- Personal Access Token
- ์๋ฐ
- injection๊ณต๊ฒฉ
- ์ฝ๋ฉํ ์คํธ
- oauth
- node.js mysql ์ฐ๋
- dockerhub
- spring scheduler
- ์๊ณ ๋ฆฌ์ฆ
- Node.js
- Jenkins
- @scheduler
- ํฌ๋ก์ค์ฌ์ดํธ ์คํฌ๋ฆฝํธ
- spring
- SpringBoot
- GoogleLogin
- java์ฑํ
- ๋ ผ๋ธ๋กํน
- ์ฝํ
- CICD
- MySQL
- db์ ๋ต
- docker
- ์ค๋ธ์
- React
- ํฐ์คํ ๋ฆฌ์ฑ๋ฆฐ์ง
- Java
- Today
- Total
<Hello Hosung๐/>
[SpringBoot] ์์กด์ฑ ์ฃผ์ (Dependency Injection) ๊ฐ๋ ๊ณผ ํ์ฉ ๋ณธ๋ฌธ
[SpringBoot] ์์กด์ฑ ์ฃผ์ (Dependency Injection) ๊ฐ๋ ๊ณผ ํ์ฉ
์ข์ถฉ์ฐ๋ ๋ฐฑ์๋ ๊ฐ๋ฐ์ ์ผ๊ธฐ๐ง 2024. 11. 8. 08:19Spring Boot๋ ์์กด์ฑ ์ฃผ์ (Dependency Injection, DI)์ ํตํด ๊ฐ์ฒด ๊ฐ์ ๊ด๊ณ๋ฅผ ๊ด๋ฆฌํ๊ณ , ๊ฐ์ฒด์ ์์ฑ๊ณผ ๊ด๊ณ ์ค์ ์ Spring ์ปจํ ์ด๋๊ฐ ๋ด๋นํ๊ฒ ๋ง๋ค์ด ์ฃผ๋ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ฝ๋์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๊ณ , ๊ฐ์ฒด๋ค์ ์ฌ์ฌ์ฉ์ฑ๊ณผ ํ ์คํธ ์ฉ์ด์ฑ์ ๋์ผ ์ ์์ต๋๋ค. ์ด๋ฒ ๋ธ๋ก๊ทธ์์๋ Spring Boot์์ ์์กด์ฑ ์ฃผ์ ์ ๊ฐ๋ ๊ณผ ์ค์ ์์๋ฅผ ํตํด ์ด๋ฅผ ์ด๋ป๊ฒ ํ์ฉํ ์ ์๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค.
1. ์์กด์ฑ ์ฃผ์ (Dependency Injection)๋?
**์์กด์ฑ ์ฃผ์
(DI)**์ ๊ฐ์ฒด๊ฐ ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ง์ ์์ฑํ์ง ์๊ณ , ์ธ๋ถ์์ ์์กด ๊ฐ์ฒด๋ฅผ ์ฃผ์
๋ฐ๋๋ก ํ๋ ์ค๊ณ ํจํด์
๋๋ค. ๊ฐ์ฒด๊ฐ ์์ ์ ์์กด์ฑ์ ์ง์ ๊ด๋ฆฌํ๋ ๋์ , Spring๊ณผ ๊ฐ์ IoC(Inversion of Control) ์ปจํ
์ด๋๊ฐ ์์กด์ฑ์ ๊ด๋ฆฌํ๊ณ ์ฃผ์
ํด์ค๋๋ค. ์ด๋ฅผ ํตํด ์ฝ๋์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๊ณ , ๊ฐ ๊ฐ์ฒด๋ค์ด ๋
๋ฆฝ์ ์ผ๋ก ๋์ํ ์ ์๊ฒ ๋ง๋ค์ด ์ค๋๋ค.
์์กด์ฑ ์ฃผ์
์ ์ฅ์
์ ์ฐ์ฑ: ์์กด ๊ด๊ณ๊ฐ ์ค์ ํ์ผ์ด๋ ์ค์ ํด๋์ค์์๋ง ๊ฒฐ์ ๋๋ฏ๋ก ์ฝ๋์ ์ ์ฐ์ฑ์ด ์ฆ๊ฐํฉ๋๋ค.
ํ
์คํธ ์ฉ์ด์ฑ: ์ค์ ๊ฐ์ฒด ๋์ Mock ๊ฐ์ฒด๋ฅผ ์ฃผ์
ํ์ฌ ๋จ์ ํ
์คํธ๋ฅผ ์ฉ์ดํ๊ฒ ํ ์ ์์ต๋๋ค.
๋ชจ๋ํ: ๊ฐ ๋ชจ๋์ด ๋
๋ฆฝ์ ์ด๊ฒ ๋์ด ์ ์ง๋ณด์๊ฐ ์ฌ์์ง๋๋ค.
Spring Boot์์๋ @Autowired, @Component, @Service ๋ฑ์ ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ์ฌ ์์กด์ฑ ์ฃผ์
์ ์ฝ๊ฒ ๊ตฌํํ ์ ์์ต๋๋ค.
2. new ๋์ Spring์ ์์กด์ฑ ์ฃผ์
์ผ๋ฐ์ ์ผ๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋๋ new ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ง์ ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค
UserRepository userRepository = new UserRepository();
UserService userService = new UserService(userRepository);
์์ ๊ฐ์ด ๊ฐ์ฒด๋ฅผ ์ง์ ์์ฑํ๊ณ , ์์กด์ฑ์ ์ฝ๋์์ ์๋์ผ๋ก ์ค์ ํ๋ ๋ฐฉ์์
๋๋ค. ํ์ง๋ง Spring์์๋ ์์กด์ฑ ์ฃผ์
์ ํตํด Spring ์ปจํ
์ด๋๊ฐ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์ฃผ์
ํด์ฃผ๋ฏ๋ก, ๊ฐ๋ฐ์๋ ๊ฐ์ฒด ์์ฑ์ ๋ํ ๊ด๋ฆฌ์์ ๋ฒ์ด๋ ๋น์ฆ๋์ค ๋ก์ง์๋ง ์ง์คํ ์ ์์ต๋๋ค.
Spring์์ ์์กด์ฑ ์ฃผ์
์ ํ์ฉํ๋ฉด, **new**๋ฅผ ์ฌ์ฉํ ๊ฐ์ฒด ์์ฑ ๋ฐฉ์ ๋์ , Spring ์ปจํ
์ด๋๊ฐ ์์กด์ฑ ๊ฐ์ฒด๋ฅผ ์๋์ผ๋ก ์์ฑํ๊ณ ์ฃผ์
ํด์ค๋๋ค.
3. Spring์์ ์์กด์ฑ ์ฃผ์ ์ฌ์ฉํ๊ธฐ
Spring Boot์์๋ @Autowired, @Component, **@Service**์ ๊ฐ์ ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ์ฌ ์์กด์ฑ ์ฃผ์
์ ์ค์ ํ ์ ์์ต๋๋ค.
3.1. ์์: UserService ํด๋์ค์์ ์์กด์ฑ ์ฃผ์
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
// ์์ฑ์ ์ฃผ์
(DI)
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void registerUser(User user) {
userRepository.save(user);
}
}
์ ์ฝ๋์์ UserService๋ UserRepository๋ฅผ ์์ฑ์๋ฅผ ํตํด ์ฃผ์
๋ฐ์ต๋๋ค. Spring์ UserRepository ๊ฐ์ฒด๋ฅผ ์๋์ผ๋ก ์์ฑํ์ฌ **UserService**์ ์ฃผ์
ํด ์ค๋๋ค. ์ด์ new UserRepository()๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ ํ์๊ฐ ์์ฃ .
3.2. @Autowired๋ก ์์กด์ฑ ์ฃผ์
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserRepository userRepository; // Spring์ด ์๋์ผ๋ก ์ฃผ์
public void registerUser(User user) {
userRepository.save(user);
}
}
@Autowired ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ๋ฉด, Spring์ด UserRepository ๊ฐ์ฒด๋ฅผ ์๋์ผ๋ก ์ฐพ์์ ์ฃผ์
ํฉ๋๋ค. ๋ ์ด์ new๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ฑฐ๋ ์์กด์ฑ์ ์ฝ๋์์ ์ง์ ์ค์ ํ ํ์๊ฐ ์์ต๋๋ค.
4. ์์กด์ฑ ์ฃผ์ ์ ๋ฐฉ์
Spring Boot์์ ์์กด์ฑ ์ฃผ์
์ ํฌ๊ฒ ์ธ ๊ฐ์ง ๋ฐฉ์์ผ๋ก ์ ๊ณต๋ฉ๋๋ค.
ํ๋ ์ฃผ์
(Field Injection): @Autowired ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ์ฌ ํ๋์ ์์กด์ฑ์ ์ฃผ์
ํ๋ ๋ฐฉ๋ฒ.
์์ฑ์ ์ฃผ์
(Constructor Injection): ์์ฑ์์ ์์กด์ฑ์ ์ฃผ์
ํ๋ ๋ฐฉ๋ฒ.
์ธํฐ ์ฃผ์
(Setter Injection): ์ธํฐ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์์กด์ฑ์ ์ฃผ์
ํ๋ ๋ฐฉ๋ฒ.
4.1. ํ๋ ์ฃผ์
(Field Injection)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
// ์์กด์ฑ ์ฃผ์
(Field Injection)
@Autowired
private UserRepository userRepository;
public void saveUser(User user) {
userRepository.save(user);
}
}
ํ๋ ์ฃผ์
์ ์ง๊ด์ ์ด๊ณ ๊ฐ๋จํ์ง๋ง, ํ
์คํธ๊ฐ ์ด๋ ต๊ณ ์์กด์ฑ์ด ๋ช
ํํ์ง ์์ ์ฝ๋๊ฐ ๋ณต์กํด์ง ์ ์์ต๋๋ค.
4.2. ์์ฑ์ ์ฃผ์
(Constructor Injection)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
// ์์ฑ์ ์ฃผ์
(Constructor Injection)
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void saveUser(User user) {
userRepository.save(user);
}
}
์์ฑ์ ์ฃผ์
์ ์์กด์ฑ ์ฃผ์
์ ๋ถ๋ณ ๊ฐ์ฒด์ฒ๋ผ ์ฒ๋ฆฌํ ์ ์์ด ์์ ํ๊ณ , ํ
์คํธํ ๋ Mock ๊ฐ์ฒด๋ฅผ ์ฝ๊ฒ ์ฃผ์
ํ ์ ์์ต๋๋ค. Spring 4.3 ์ด์์์๋ @Autowired ์ด๋
ธํ
์ด์
์ ์์ฑ์์ ์๋ตํ ์ ์์ต๋๋ค.
4.3. ์ธํฐ ์ฃผ์
(Setter Injection)
import org.springframework.stereotype.Service;
@Service
public class UserService {
private UserRepository userRepository;
// ์ธํฐ ์ฃผ์
(Setter Injection)
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void saveUser(User user) {
userRepository.save(user);
}
}
์ธํฐ ์ฃผ์
์ ๊ฐ์ฒด๊ฐ ์์ฑ๋ ํ ์์กด์ฑ์ ์ค์ ํ ์ ์๋ ์ฅ์ ์ด ์์ง๋ง, ์์กด์ฑ ์ค์ ์ด ๋๋ฝ๋ ์ํ์ด ์๊ธฐ ๋๋ฌธ์ ์์ฑ์ ์ฃผ์
๋ณด๋ค ์์ ์ฑ์ ๋จ์ด์ง ์ ์์ต๋๋ค.
5. ์์กด์ฑ ์ฃผ์ ํ์ฉ ์์
์์ 1: ์ฌ์ฉ์ ์๋น์ค ๊ตฌํ
UserRepository ์ธํฐํ์ด์ค
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
UserService ํด๋์ค (์์กด์ฑ ์ฃผ์
)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void registerUser(User user) {
userRepository.save(user);
}
}
UserController ํด๋์ค (UserService ์ฃผ์ )
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@PostMapping("/register")
public String registerUser(@RequestBody User user) {
userService.registerUser(user);
return "User registered successfully!";
}
}
6. ์์กด์ฑ ์ฃผ์
์ ํ์ฉํ ํ
์คํธ
Spring Boot์์ ์์กด์ฑ ์ฃผ์
์ ํ์ฉํ๋ฉด ํ
์คํธ๋ฅผ ๋์ฑ ์ฝ๊ฒ ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, UserService๋ฅผ ํ
์คํธํ ๋, UserRepository๋ฅผ ์ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๊ฒฐํ์ง ์๊ณ Mock ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ํ
์คํธํ ์ ์์ต๋๋ค.
ํ
์คํธ ์์
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
public void testRegisterUser() {
User user = new User("John Doe", "john@example.com");
doNothing().when(userRepository).save(user);
userService.registerUser(user);
verify(userRepository, times(1)).save(user);
}
}
์์ ์์์ฒ๋ผ, @Mock ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํด UserRepository๋ฅผ Mock ๊ฐ์ฒด๋ก ๋ง๋ค๊ณ , @InjectMocks๋ก UserService์ ์์กด์ฑ์ ์ฃผ์
ํ์ฌ ํ
์คํธํ ์ ์์ต๋๋ค.
7. ๋ง๋ฌด๋ฆฌ
Spring Boot์์ ์์กด์ฑ ์ฃผ์
์ ๊ฐ์ฒด ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ช
ํํ๊ฒ ์ค์ ํ๊ณ , ์ฝ๋์ ์ ์ฐ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๋์ฌ์ค๋๋ค. ๋ํ, ํ
์คํธ๋ฅผ ์ฉ์ดํ๊ฒ ํ์ฌ ์ฝ๋์ ํ์ง์ ํฅ์์ํฌ ์ ์์ต๋๋ค. ๋ค์ํ ์์กด์ฑ ์ฃผ์
๋ฐฉ์์ ์ ํ์ฉํ์ฌ, ๋ ๋์ Spring ์ ํ๋ฆฌ์ผ์ด์
์ ๊ฐ๋ฐ ํ ์ ์์ต๋๋ค.
'๐ป Java > ใ คJava(SpringBoot)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[SpringBoot] Spring Security๋ฅผ ํ์ฉํ ์ธ์ฆ ๋ฐ ๊ถํ (1) | 2024.11.23 |
---|---|
[Spring] AOP ๊ฐ๋ ๋ถํฐ ๋ก๊น ์์ ๊น์ง ํ ๋ฒ์ ์ดํดํ๊ธฐ (0) | 2024.11.17 |
[SpringBoot]Scheduling (0) | 2024.08.16 |