๋์ฒด Bean์ด ๋ญ๊ณ ์ ํ์ํ๋ฐ???
๋น(Bean)์ด๋?
์คํ๋ง์ด ๋์ newํด์ ์์ฑํ๊ณ ์ฑ ์ ๋ฐ์์ ์ธ ์ ์๋๋ก ๊ด๋ฆฌํด์ฃผ๋ ๊ฐ์ฒด
๋ฆฌ์กํธ๋ก ๋น์ ํด ๋ณด์๋ฉด,
๋น(Bean) = Context Provider์ ๋ฑ๋ก๋ ๊ฐ.
์คํ๋ง์ด Provider์ญํ ์ ํด์ ๋น์ ๋ฏธ๋ฆฌ ๋ง๋ค์ด๋๊ณ ์ด๋์๋ @Autowired (โuseContext)๋ก ๊บผ๋ด๋ ๊ตฌ์กฐ!
๋น(Bean)์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฑ๊ธํค(ํ ๋ฒ๋ง ๋ง๋ค์ด์ ธ์ ์ ์ฒด ๊ณต์ )
๋น(Bean)์ ๋ค์ด๊ฐ ๊ฐ์ new ํด๋์ค()๋ก ๋ง๋ ๊ฐ์ฒด(=์ธ์คํด์ค)์ด๋ค.
์ฆ, ํด๋์ค๋ ์ค๊ณ๋์ด๊ณ , ๊ทธ ์ค๊ณ๋๋ก ๋ง๋ ๊ฐ์ฒด๊ฐ ์คํ๋ง ์ปจํ ์ด๋์ Bean์ผ๋ก ๋ค์ด๊ฐ๋ค.
์ด ๊ฐ์ฒด๋ ์คํ๋ง์ด ๋์ new ํด์ ๋ง๋ค์ด์ฃผ๊ณ , ์ฑ ์ ์ฒด์์ ๊บผ๋ด์ธ ์ ์๊ฒ ๊ด๋ฆฌํด์ค๋ค.
์ ๊ตณ์ด ์คํ๋ง์ด ๊ฐ์ฒด๋ฅผ ๋์ ๋ง๋ค๊ณ ๊ด๋ฆฌํ๊ฒ ํ๋๋ฐ
1. new๋ฅผ ์์จ๋ ๋จ.(์๋์ฐ๊ฒฐ)
์๋ฅผ๋ค๋ฉด React์์ props๋ด๋ ค์ฃผ๋ ๊ตฌ์กฐ๊ฐ ์๋ ์ฝ๋์ ๊ฐ๋ค๋ฉด
<App>
<Page user={user}>
<Profile user={user} />
</Page>
</App>
๋ฌธ์ ๋ ์ค๊ฐ ์ปดํฌ๋ํธ(Page)๋ user์์, ๊ทธ๋ผ์๋ ๋ด๋ ค์ค์ผ ํจ
ํด๊ฒฐ์ฑ ์ผ๋ก๋ Context์จ์ ์ด๋์๋ ๋ฐ๋ก ๊บผ๋ด์ฐ๊ธฐ.
๊ทธ๋์ Spring์์ ๋น์ ๋ฏธ๋ฆฌ ๋ง๋ค์ด์ฃผ๊ณ ์๋์ผ๋ก ์ฃผ์ ํ๋ ๊ตฌ์กฐ๋ค.
@Service
public class ProfileService {
private final UserRepository userRepository;
// ์์ฑ์์ @Autowired → ์คํ๋ง์ด ์์์ ๋น์ ์ฐ๊ฒฐํด์ค
public ProfileService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
๊ฒฐ๊ณผ๋ก๋ ์ง์ new UserRepository() ์ํด๋ ๋จ.
์คํ๋ง์ด ๋์ ๋ง๋ค์ด์ ๋ฃ์ด์ค
2.ํ ๋ฒ๋ง ๋ง๋ค์ด์ ์ ์ฒด ๊ณต์ (์ฑ๊ธํค)
React์ Context์ ๋ฃ๋ ๊ฐ์ฒด๋ ์ ์ฒด๊ณต์ ๊ฐ ๊ฐ๋ฅํ๋ค. ์ด์ ๋น์ทํจ
<DataContext.Provider value={myApiClient}>
<App />
</DataContext.Provider>
Spring ๊ธฐ๋ณธ์ ์ผ๋ก ๋น์ ์ฑ๊ธํค, ํ ๋ฒ๋ง ๋ง๋ค์ด์ ธ์ ์ด๋์๋ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค๋ ํน์ง์ด ์๋ค.
@Configuration
public class AppConfig {
@Bean
public ApiClient apiClient() {
return new ApiClient("https://api.example.com");
}
}
apiClient()๋ ์ ํ๋ฆฌ์ผ์ด์ ์คํ ์ค ๋จ 1๋ฒ๋ง ํธ์ถ
3. ํ ์คํธํ ๋๋ ํธํจ
@TestConfiguration
public class TestConfig {
@Bean
public ApiClient fakeApiClient() {
return new FakeApiClient(); // ํ
์คํธ์ฉ ๊ฐ์ฒด!
}
}
์ค์ ๊ตฌํ์ฒด๋ฅผ ๋ฐ๊พธ์ง ์๊ณ ๋ ํ ์คํธ์ฉ์ผ๋ก ๊ต์ฒด๊ฐ ๊ฐ๋ฅํ๋ค
์ด๊ฒ ๋ค ๋น๋ฑ๋ก์ ํตํด ์์กด์ฑ ์ฐ๊ฒฐ์ ์คํ๋ง์ด ๋งก๊ธฐ๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฅ
์ด๋ป๊ฒ ๋ฑ๋กํ๊ณ ๊บผ๋ด์ฐ๋๋ฐ?
→ ComponentScan = ์๋ ๋ฑ๋กํด์ฃผ๋ ๊ธฐ๋ฅ
→ @Bean = ์ง์ ๋ฑ๋กํด์ฃผ๋ ๊ธฐ๋ฅ
@ComponentScan: "์๋ ๋ฑ๋ก๊ธฐ"
๋ฌด์จ๋ง์ด๋๋ฉด,
์๋ฅผ๋ค๋ฉด, React๋ก ์น๋ฉด, ๋ด๊ฐ ๋ง๋ ์ปดํฌ๋ํธ๋ฅผ App.js์์ ์ผ์ผ์ด import ์ํด๋ src/ components /ํด๋์ ์ ์ฒด๋ฅผ ์๋์ผ๋ก ์ค์บํด์ ๋ฑ๋กํด์ฃผ๋ ๊ธฐ๋ฅ
Spring์์ ์๋ ์ฝ๋์ ๊ฐ๋ค.
@Component
public class MyService {
public void doSomething() {
System.out.println("Spring Bean!");
}
}
์ด ํด๋์ค๊ฐ ์๋ ์์น๋ฅผ ๊ธฐ์ค์ผ๋ก ์คํ๋ง์ด ์๋์ผ๋ก ์ค์บํ๋ค.
@SpringBootApllication์ด ์๋ ํด๋์ค ๊ธฐ์ค์ผ๋ก ํ์ ํจํค์ง๋ฅผ ๋ค์ ธ์ ์ด๋ฐ @Component, @Service, @Controller, @Repository๊ฐ ๋ถ์ ๊ฑธ ์ ๋ถ Bean์ผ๋ก ๋ฑ๋กํด์ค๋ค.
์ฆ, ์ผ์ผ์ด ๋ฑ๋กํ์ง ์์๋ ๊ทธ๋ฅ ์๋์ผ๋ก ๋ฑ๋กํด์ค์ ํธํ๋ค.
๋น์ ๋ฅผ ํด๋ณด์๋ฉด,
React์์ components/ํด๋์ ์๋ ๋ชจ๋ ํ์ผ์ ์๋์ผ๋ก importํด์ฃผ๋ ๋๋
(์ค์ ๋ก๋ ๊ทธ๋ ์ง ์์ง๋ง, ๊ทธ๋ฐ ์๋ํ์๊ธฐ ์ญํ ์ ํ๋ค๊ณ ์ดํดํ๋ฉด ๋ฑ ์ข์)
@SpringBootApplication์ด ์ ์ค์ํจ?
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
์ด @SpringBootApllication์์ ์ด๋ฏธ @ComponentScan์ด ํฌํจ๋ผ ์์
์ฆ, ์ด ํด๋์ค๊ฐ ์๋ ํจํค์ง๋ฅผ ๊ธฐ์ค์ผ๋ก ์๋์ ์๋ ๋ชจ๋ @Components๋ค์ ๋ฑ๋กํด์ค๋ผ๋ ์๋ฏธ๋ค.
๊ทธ๋์ MainApplication์ ์์น๊ฐ ์์ฒญ ์ค์ํจ.
๋๋ฌด ํ์์ ์์ผ๋ฉด ์์ ์๋ ๊ฒ๋ค์ ์ค์บ ๋ชปํจ
์๋ ๋ฑ๋ก์ด ์ซ๊ณ ์ง์ ๋ฑ๋กํ๊ณ ์ถ์ ๋? (@Bean)
React์์ Context.Provider์์ ๊ฐ์ ๋ช ์์ ์ผ๋ก ๋ฃ์ด์ฃผ๋ ๋๋์ด๋ผ๊ณ ์ดํดํ๋ฉด ๋๋ค.
@Bean์ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ฐ์ฒด๋ ๋ด๊ฐ ์ปจํธ๋กค ๋ชปํ๋ ํด๋์ค๋ฅผ ๋น์ผ๋ก ๋ฑ๋กํ ๋ ์ ์ฉํ๋ค.
Spring์ฝ๋๋ ์๋์ ๊ฐ๋ค
@Configuration // "์ด ํด๋์ค๋ Bean ๋ฑ๋ก์ฉ ํด๋์ค์ผ"
public class AppConfig {
@Bean // "์ด ๋ฉ์๋๊ฐ ๋ฐํํ๋ ๊ฐ์ฒด๋ฅผ Spring Bean์ผ๋ก ๋ฑ๋กํด์ค!"
public TestService testService() {
return new TestServiceImpl();
}
}
์ด์ ๋ถํฐ๋ testService()๊ฐ ๋ฐํํ๋ TestServiceImpl๊ฐ์ฒด๊ฐ ์คํ๋ง ์ปจํ ์ด๋ ์์ ๋ค์ด๊ฐ๋ค.
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
TestService service = context.getBean(TestService.class);
React๋ก ์น๋ฉด, Context.Provider์์ value={myService} ๋ฃ์ด์ค ๋๋.
Bean ์ถฉ๋์ด ๋ฌ์ ๋?
๋ ๊ฐ์ ๊ฐ์ ์ด๋ฆ์ ๊ฐ์ง Bean์ด ์์ผ๋ฉด?
@Component("service") // ์๋ ๋ฑ๋ก
public class ConflictServiceV1 implements ConflictService {...}
@Component("service") // ์๋ ๋ฑ๋ก
public class ConflictServiceV2 implements ConflictService {...}
์ด๊ฑด ๋ง์น Context.Provider ์์ ๋ ๊ฐ์ value๋ฅผ ๋์์ ๋ฃ์ผ๋ ค๋ ๊ฑฐ์
์คํ๋ง์ ConflictingBeanDefinitionException ์๋ฌ๋ฅผ ๋ฑ์(๋๊ตด ์ธ์ง ๋ชจ๋ฅด๋๊น!)
๊ทธ๋ด ๋?
- ์๋ ๋ฑ๋ก์ด ์ฐ์ ๊ถ์ ๊ฐ์ง๋ค.
- ์ฆ, ์๋์ผ๋ก ๋ฑ๋กํ @Bean์ด ์๋ ๋ฑ๋ก๋ @Component๋ณด๋ค ๋จผ์ ๋จนํ๊ฒ ๋๋ค.
- ์ค์๋ก ์ด๋ฆ ๊ฒน์น๋ฉด ์ง์ง ๋ฒ๊ทธ๋จ.
- ๊ทธ๋์ Spring Boot์์๋ ์ถฉ๋ํ๋ฉด ์ ์ด์ ์คํ ์คํด ๋ด๋ฒ๋ฆฌ๋ ์ ์ฑ ์ ์. ์ด๊ฒ ๋ ์์ ํ๋ค.
์์์ฝ๋๋ก ๋ณด๋ Bean
com.example
โโโ MyApplication.java // ์ฌ๊ธฐ @SpringBootApplication ๋ถ์
โโโ controller/
โ โโโ HelloController.java (@RestController)
โโโ service/
โ โโโ GreetingServiceImpl.java (@Service)
// 1. ์ธํฐํ์ด์ค ์ ์ธ: ์ญํ ์ ์
public interface GreetingService {
String greet(String name);
}
// 2. ์ธํฐํ์ด์ค ๊ตฌํ์ฒด ๋ง๋ค๊ธฐ
@Service // ComponentScan์ ์ํด ์๋์ผ๋ก ๋น ๋ฑ๋ก๋จ
// ComponentScan๋ฅผ ์ ์ธ ์ ํ๋๋ฐ ์ด๋ป๊ฒ ์๋ ๋ฑ๋ก์ด ๋๋๊ฐ?
// @SpringBootApplication์์ @ComponentScan์ด ๋ค์ด์๊ธฐ ๋๋ฌธ.
public class GreetingServiceImpl implements GreetingService {
@Override
public String greet(String name) {
return "์๋
ํ์ธ์, " + name + "๋!";
}
}
์ ์ฝ๋์์ @ComponentScan ์ ์ธ ์ ํ๋๋ฐ ์ด๋ป๊ฒ ์๋๋ฑ๋ก์ด ๋๋์ง ๊ฐ๋ตํ๊ฒ ์ค๋ช ํ๊ณ ๋์ด๊ฐ๊ฒ ๋ค.
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
์ด๋ ๊ฒ ์คํ๋ง๋ถํธ ํ๋ก์ ํธ๋ฅผ ์์ํ๋ฉด, @SpringBootApllication์ด ์๋์ผ๋ก @ComponentScan์ ํฌํจํ๊ณ ์์ด์
๋ณ๋๋ก @ComponentScan์ ์ ์ธํ์ง ์์๋ ๋จ.
// ์ค์ ๋ก @SpringBootApplication์๋ ์ด๋ฐ ์ฝ๋๊ฐ ์์
@SpringBootApplication
= @Configuration
+ @EnableAutoConfiguration
+ @ComponentScan ์๊ฒ ํฌํจ๋์ด ์์!!!
์ฆ, @SpringBootApplication = 3๊ฐ๋ฅผ ํ ๋ฒ์ ๋ถ์ธ ํจ๊ณผ
// 3. ์ด ์๋น์ค๋ฅผ ์ฌ์ฉํ๋ ์ปจํธ๋กค๋ฌ
@RestController
public class HelloController {
private final GreetingService greetingService;
// 4. ์์ฑ์ ์ฃผ์
: ์คํ๋ง์ด GreetingServiceImpl์ ์๋์ผ๋ก ๋ฃ์ด์ค!
public HelloController(GreetingService greetingService) {
this.greetingService = greetingService;
}
// 5. ๋ธ๋ผ์ฐ์ ์์ /hello?name=ํ์ → ์ด ๋ฉ์๋ ์คํ
@GetMapping("/hello")
public String hello(@RequestParam String name) {
return greetingService.greet(name); // ์ค์ ๊ตฌํ์ฒด ๋ฉ์๋ ํธ์ถ
}
}
'Backend > ๐ฑ Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [Spring] Bean Validation (5) | 2025.07.28 |
|---|---|
| [Spring]์์กด๊ด๊ณ ์ฃผ์ (DI) (2) | 2025.07.28 |
| [Spring] Layered Architecture (3) | 2025.07.26 |
| [Spring] Mapping (1) | 2025.07.23 |
| [Spring]MVC (4) | 2025.07.23 |