• ABOUT
  • PORTFOLIO
  • POSTS
  • GUESTBOOK

ยฉ 2025 BlueCool12 All rights reserved.

2025.09.07Spring

๐Ÿงฉ Spring Bean ๋“ฑ๋ก ์–ด๋…ธํ…Œ์ด์…˜ ์ •๋ฆฌ: @Component๋ถ€ํ„ฐ @Repository๊นŒ์ง€

1. Spring Bean

Spring Bean์€ Spring์˜ IoC ์ปจํ…Œ์ด๋„ˆ์— ์˜ํ•ด ์ƒ์„ฑ๋˜๊ณ  ๊ด€๋ฆฌ๋˜๋Š” ์ž๋ฐ” ๊ฐ์ฒด๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ์ž๋ฐ” ํด๋ž˜์Šค๊ฐ€ Spring ์ปจํ…Œ์ด๋„ˆ์˜ ๊ด€๋ฆฌ ๋Œ€์ƒ์œผ๋กœ ๋“ฑ๋ก๋˜๋Š” ์ˆœ๊ฐ„ ํ•ด๋‹น ๊ฐ์ฒด๋Š” Bean์ด๋ผ๊ณ  ๋ถˆ๋ฆฐ๋‹ค.

์ผ๋ฐ˜์ ์ธ Java ๊ฐ์ฒด๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ new ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด ์ง์ ‘ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ฐ์ฒด ๊ฐ„์˜ ์˜์กด ๊ด€๊ณ„๋„ ์ฝ”๋“œ์—์„œ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •ํ•œ๋‹ค. ๋ฐ˜๋ฉด Spring์—์„œ๋Š” ๊ฐ์ฒด์˜ ์ƒ์„ฑ๊ณผ ์ƒ๋ช…์ฃผ๊ธฐ ๊ด€๋ฆฌ๊ฐ€ ์ปจํ…Œ์ด๋„ˆ์— ์˜ํ•ด ์ด๋ฃจ์–ด์ง„๋‹ค.

Spring ์ปจํ…Œ์ด๋„ˆ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์‹œ ํ•„์š”ํ•œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜๋ฉฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ข…๋ฃŒ ์‹œ ๊ฐ์ฒด์˜ ์†Œ๋ฉธ๊นŒ์ง€ ๊ด€๋ฆฌํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ฐœ๋ฐœ์ž๋Š” ๊ฐ์ฒด ์ƒ์„ฑ๊ณผ ์˜์กด ๊ด€๊ณ„ ๊ด€๋ฆฌ ๋Œ€์‹  ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๊ตฌํ˜„์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋‹ค.


2. Spring Bean ๋“ฑ๋ก ๋ฐฉ๋ฒ•

Spring์—์„œ ๊ฐ์ฒด๋ฅผ Bean์œผ๋กœ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.


- ์ปดํฌ๋„ŒํŠธ ์Šค์บ” (Component Scan)

Spring์ด ํŠน์ • ํŒจํ‚ค์ง€๋ฅผ ์Šค์บ”ํ•˜์—ฌ ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ํด๋ž˜์Šค๋ฅผ ์ž๋™์œผ๋กœ Bean์œผ๋กœ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

๋Œ€ํ‘œ์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์–ด๋…ธํ…Œ์ด์…˜์ด ์‚ฌ์šฉ๋œ๋‹ค.

  • @Component
  • @Service
  • @Repository
  • @Controller
  • @RestController

Spring Boot์—์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฉ”์ธ ํด๋ž˜์Šค๊ฐ€ ์œ„์น˜ํ•œ ํŒจํ‚ค์ง€๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•˜์œ„ ํŒจํ‚ค์ง€๋ฅผ ์ž๋™ ์Šค์บ”ํ•œ๋‹ค. ์ด๋Š” @SpringBootApplication ๋‚ด๋ถ€์— @ComponentScan์ด ํฌํ•จ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.


- Java Config ๋ฐฉ์‹ (@Bean)

๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ์„ค์ • ํด๋ž˜์Šค์—์„œ Bean์„ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

@Configuration
public class AppConfig {

@Bean
public MemberService memberService() {
return new MemberService();
}
}

์ด ๋ฐฉ์‹์€ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ฐ์ฒด๋ฅผ Bean์œผ๋กœ ๋“ฑ๋กํ•˜๊ฑฐ๋‚˜ ๊ฐ์ฒด ์ƒ์„ฑ ๊ณผ์ •์„ ์ง์ ‘ ์ œ์–ดํ•ด์•ผ ํ•  ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.


3. Spring Bean ๋“ฑ๋ก ์–ด๋…ธํ…Œ์ด์…˜

1) @Component

@Component
public class UserService {
}

@Component๋Š” Spring์—์„œ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ด ๋˜๋Š” Bean ๋“ฑ๋ก ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค. ํด๋ž˜์Šค์— ์ด ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ถ™์ด๋ฉด ์ปดํฌ๋„ŒํŠธ ์Šค์บ” ๋Œ€์ƒ์ด ๋˜์–ด Spring ์ปจํ…Œ์ด๋„ˆ์— Bean์œผ๋กœ ๋“ฑ๋ก๋œ๋‹ค.

์ดํ›„์— ๋“ฑ์žฅํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜๋“ค(@Controller, @Service, @Repository ๋“ฑ)์€ ๋ชจ๋‘ ๋‚ด๋ถ€์ ์œผ๋กœ @Component๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ํŠน์ˆ˜ํ™”๋œ ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค.

์ฆ‰ ์ด๋Ÿฌํ•œ ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•œ ํด๋ž˜์Šค ์—ญ์‹œ @Component์™€ ๋™์ผํ•˜๊ฒŒ Spring์ด ์ž๋™์œผ๋กœ Bean์œผ๋กœ ๋“ฑ๋กํ•˜๊ณ  ์ƒ๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.

์•„๋ž˜๋Š” @Service ์–ด๋…ธํ…Œ์ด์…˜์˜ ์‹ค์ œ ์ฝ”๋“œ ์ผ๋ถ€์ด๋‹ค. 

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
/**
* Alias for {@link Component#value}.
*/
@AliasFor(annotation = Component.class)
String value() default "";
}

@Component ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์–ด๋…ธํ…Œ์ด์…˜์„ ๊ตฌ๋ถ„ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•˜๊ณ  ๊ฐ ํด๋ž˜์Šค์˜ ์—ญํ• ์„ ๋ถ„๋ช…ํ•˜๊ฒŒ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค.

๊ณ„์ธต์— ๋”ฐ๋ผ ์–ด๋…ธํ…Œ์ด์…˜์„ ๋‹ค๋ฅด๊ฒŒ ์ ์šฉํ•˜๋ฉด ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์ด ์ข‹์•„์ง€๊ณ  ์—ญํ• ์— ๋”ฐ๋ฅธ ๊ด€์‹ฌ์‚ฌ ๋ถ„๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง„๋‹ค. ์ด๋Ÿฌํ•œ ๊ตฌ์กฐ๋Š” AOP๋ฅผ ์ ์šฉํ•˜๊ฑฐ๋‚˜ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑ ํ•  ๋•Œ๋„ ์œ ๋ฆฌํ•˜๊ฒŒ ์ž‘์šฉ๋œ๋‹ค.


2) @Controller & @RestController

@Controller๋Š” ์ „ํ†ต์ ์ธ Spring MVC ํŒจํ„ด์—์„œ ์›น ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  View๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค. 

์ด ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ํด๋ž˜์Šค๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ๋ฐ›์•„ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ํ˜ธ์ถœํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ Model์— ๋‹ด์•„ View๋กœ ์ „๋‹ฌํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. 

@Controller
public class MainController {

@GetMapping("/")
public String home(Model model) {
model.addAttribute("msg", "Hello World");
return "home"; // home.html ํ˜น์€ home.jsp View ๋ Œ๋”๋ง
}
}

๋ฐ˜๋ฉด @RestController๋Š” @Controller์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ ๋‚ด๋ถ€์ ์œผ๋กœ @ResponseBody๊ฐ€ ํ•จ๊ป˜ ์ ์šฉ๋œ ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค.

๋”ฐ๋ผ์„œ ๋ฉ”์„œ๋“œ์˜ ๋ฐ˜ํ™˜ ๊ฐ’์ด View ์ด๋ฆ„์ด ์•„๋‹ˆ๋ผ JSON์ด๋‚˜ XML๊ณผ ๊ฐ™์€ ๋ฐ์ดํ„ฐ ํ˜•ํƒœ๋กœ HTTP ์‘๋‹ต ๋ณธ๋ฌธ์— ์ง์ ‘ ์ „๋‹ฌ๋œ๋‹ค.

@RestController
public class ApiController {

@GetMapping("/api/hello")
public String hello() {
return "Hello I'm BlueCool"; // ๋ฌธ์ž์—ด์ด ๊ทธ๋Œ€๋กœ HTTP ์‘๋‹ต ๋ณธ๋ฌธ์œผ๋กœ ์ „์†ก
}
}

์ •๋ฆฌํ•˜๋ฉด @Controller๋Š” ํ…œํ”Œ๋ฆฟ ๊ธฐ๋ฐ˜์˜ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ View๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉ๋˜๋ฉฐ @RestController๋Š” RESTful API ์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ์™€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›์„ ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.


3) @Service

@Service๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋‹ด๋‹นํ•˜๋Š” ํด๋ž˜์Šค์— ์‚ฌ์šฉ๋˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์š”์ฒญ์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ๋กœ์ง(ํšŒ์› ๊ฐ€์ž…, ์•Œ๋ฆผ ๋ฐœ์†ก ๋“ฑ)์ด ์žˆ๋‹ค๋ฉด ์‹ค์ œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์€ @Service๊ฐ€ ๋ถ™์€ ํด๋ž˜์Šค์—์„œ ๊ตฌํ˜„๋œ๋‹ค.

@Service
public class MemberService {

public void registerMember(Member member) {
// ํšŒ์›๊ฐ€์ž… ์ฒ˜๋ฆฌ ๋กœ์ง
}
}

@Service ์ž์ฒด๊ฐ€ ํŠน๋ณ„ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ํ•ด๋‹น ํด๋ž˜์Šค๊ฐ€ ๋น„์ฆˆ๋‹ˆ์Šค ๊ณ„์ธต์— ์†ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ํ‘œํ˜„ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ์˜ ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์›Œ์ง€๊ณ  ์œ ์ง€๋ณด์ˆ˜์—๋„ ๋„์›€์ด ๋œ๋‹ค.

๋˜ํ•œ AOP๋ฅผ ์ ์šฉํ•  ๋•Œ @Service๊ฐ€ ๋ถ™์€ ํด๋ž˜์Šค๋งŒ์„ ๋Œ€์ƒ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋กœ๊น…์ด๋‚˜ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ์™€ ๊ฐ™์€ ๊ณตํ†ต ๊ธฐ๋Šฅ์„ ์ ์šฉํ•  ๋•Œ๋„ ์œ ์šฉํ•˜๊ฒŒ ํ™œ์šฉ๋œ๋‹ค.


4) @Repository

@Repository๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘๊ทผ์„ ๋‹ด๋‹นํ•˜๋Š” DAO ๊ณ„์ธต์— ์‚ฌ์šฉํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค.

์ด ์–ด๋…ธํ…Œ์ด์…˜์˜ ์ค‘์š”ํ•œ ํŠน์ง• ์ค‘ ํ•˜๋‚˜๋Š” Spring์˜ ์˜ˆ์™ธ ๋ณ€ํ™˜ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•œ๋‹ค๋Š” ์ ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด JDBC, JPA, Hibernate ๋“ฑ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ์˜ˆ์™ธ๋Š” ๊ธฐ์ˆ ๋งˆ๋‹ค ์„œ๋กœ ๋‹ค๋ฅธ ์˜ˆ์™ธ ํƒ€์ž…์„ ์‚ฌ์šฉํ•œ๋‹ค.

Spring์€ ์ด๋Ÿฌํ•œ ์˜ˆ์™ธ๋ฅผ DataAccessException ๊ณ„์—ด์˜ ๊ณตํ†ต ์˜ˆ์™ธ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋˜์ง€๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํŠน์ • ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๊ธฐ์ˆ ์ด๋‚˜ DB ๋ฒค๋”์— ์ข…์†๋˜์ง€ ์•Š๋Š” ์ผ๊ด€๋œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.

์ด ์˜ˆ์™ธ ๋ณ€ํ™˜ ๊ธฐ๋Šฅ์€ PersistenceExceptionTranslationPostProcessor์— ์˜ํ•ด AOP ํ”„๋ก์‹œ ํ˜•ํƒœ๋กœ ์ ์šฉ๋˜๋ฉฐ @Repository๊ฐ€ ๋ถ™์€ ํด๋ž˜์Šค์— ์ž๋™์œผ๋กœ ์ ์šฉ๋œ๋‹ค.

@Repository
public class MemberRepository {

@PersistenceContext
private EntityManager em;

public Member findById(Long id) {
return em.find(Member.class, id);
}
}

์ฐธ๊ณ ๋กœ JdbcTemplate์€ ๋‚ด๋ถ€์ ์œผ๋กœ SQLException์„ DataAccessException์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋กœ์ง์„ ์ด๋ฏธ ํฌํ•จํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— @Repository๊ฐ€ ์—†์–ด๋„ ๋™์ผํ•œ ์˜ˆ์™ธ ๋ณ€ํ™˜์ด ๋ฐœ์ƒํ•œ๋‹ค.

๋”ฐ๋ผ์„œ @Repository์˜ ์˜ˆ์™ธ ๋ณ€ํ™˜ ๊ธฐ๋Šฅ์€ JPA, Hibernate ๋˜๋Š” ์ˆœ์ˆ˜ JDBC API๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•  ๋•Œ ๋” ์˜๋ฏธ ์žˆ๊ฒŒ ์ž‘์šฉํ•œ๋‹ค.

์ด์ „ ๊ธ€
๐Ÿค ์ฝ๊ธฐ ์ข‹์€ ์ฝ”๋“œ๋ฅผ ์œ„ํ•œ ๋„ค์ด๋ฐ ์ปจ๋ฒค์…˜ ๊ฐ€์ด๋“œ
๋‹ค์Œ ๊ธ€
๐Ÿ“‹ ์ž๋ฐ”๋กœ ์ดํ•ดํ•˜๋Š” ์–•์€ ๋ณต์‚ฌ & ๊นŠ์€ ๋ณต์‚ฌ
์žฅ์‹์šฉ ๋กœ๊ณ