Spring Bean์ Spring์ IoC ์ปจํ
์ด๋์ ์ํด ์์ฑ๋๊ณ ๊ด๋ฆฌ๋๋ ์๋ฐ ๊ฐ์ฒด๋ฅผ ์๋ฏธํ๋ค. ์๋ฐ ํด๋์ค๊ฐ Spring ์ปจํ
์ด๋์ ๊ด๋ฆฌ ๋์์ผ๋ก ๋ฑ๋ก๋๋ ์๊ฐ ํด๋น ๊ฐ์ฒด๋ Bean์ด๋ผ๊ณ ๋ถ๋ฆฐ๋ค.
์ผ๋ฐ์ ์ธ Java ๊ฐ์ฒด๋ ๊ฐ๋ฐ์๊ฐ new ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํด ์ง์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๊ฐ์ฒด ๊ฐ์ ์์กด ๊ด๊ณ๋ ์ฝ๋์์ ๋ช
์์ ์ผ๋ก ์ค์ ํ๋ค. ๋ฐ๋ฉด Spring์์๋ ๊ฐ์ฒด์ ์์ฑ๊ณผ ์๋ช
์ฃผ๊ธฐ ๊ด๋ฆฌ๊ฐ ์ปจํ
์ด๋์ ์ํด ์ด๋ฃจ์ด์ง๋ค.
Spring ์ปจํ
์ด๋๋ ์ ํ๋ฆฌ์ผ์ด์
์คํ ์ ํ์ํ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์์กด์ฑ์ ์ฃผ์
ํ๋ฉฐ ์ ํ๋ฆฌ์ผ์ด์
์ข
๋ฃ ์ ๊ฐ์ฒด์ ์๋ฉธ๊น์ง ๊ด๋ฆฌํ๋ค. ์ด๋ฅผ ํตํด ๊ฐ๋ฐ์๋ ๊ฐ์ฒด ์์ฑ๊ณผ ์์กด ๊ด๊ณ ๊ด๋ฆฌ ๋์ ํต์ฌ ๋น์ฆ๋์ค ๋ก์ง ๊ตฌํ์ ์ง์คํ ์ ์๋ค.
Spring์์ ๊ฐ์ฒด๋ฅผ Bean์ผ๋ก ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ์ ํฌ๊ฒ ๋ ๊ฐ์ง๊ฐ ์๋ค.
Spring์ด ํน์ ํจํค์ง๋ฅผ ์ค์บํ์ฌ ์ด๋
ธํ
์ด์
์ด ๋ถ์ ํด๋์ค๋ฅผ ์๋์ผ๋ก Bean์ผ๋ก ๋ฑ๋กํ๋ ๋ฐฉ์์ด๋ค.
๋ํ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ์ด๋
ธํ
์ด์
์ด ์ฌ์ฉ๋๋ค.
@Component @Service @Repository @Controller @RestController Spring Boot์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฉ์ธ ํด๋์ค๊ฐ ์์นํ ํจํค์ง๋ฅผ ๊ธฐ์ค์ผ๋ก ํ์ ํจํค์ง๋ฅผ ์๋ ์ค์บํ๋ค. ์ด๋ @SpringBootApplication ๋ด๋ถ์ @ComponentScan์ด ํฌํจ๋์ด ์๊ธฐ ๋๋ฌธ์ด๋ค.
๊ฐ๋ฐ์๊ฐ ์ง์ ์ค์ ํด๋์ค์์ Bean์ ๋ฑ๋กํ๋ ๋ฐฉ์์ด๋ค.
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberService();
}
}
์ด ๋ฐฉ์์ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ฐ์ฒด๋ฅผ Bean์ผ๋ก ๋ฑ๋กํ๊ฑฐ๋ ๊ฐ์ฒด ์์ฑ ๊ณผ์ ์ ์ง์ ์ ์ดํด์ผ ํ ๋ ์ฃผ๋ก ์ฌ์ฉ๋๋ค.
@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๋ฅผ ์ ์ฉํ๊ฑฐ๋ ํ
์คํธ ์ฝ๋๋ฅผ ์์ฑ ํ ๋๋ ์ ๋ฆฌํ๊ฒ ์์ฉ๋๋ค.
@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 ์๋ฒ์์ ํด๋ผ์ด์ธํธ์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์ ๋ ์ฌ์ฉ๋๋ค.
@Service๋ ๋น์ฆ๋์ค ๋ก์ง์ ๋ด๋นํ๋ ํด๋์ค์ ์ฌ์ฉ๋๋ ์ด๋
ธํ
์ด์
์ด๋ค.
์๋ฅผ ๋ค์ด ์ปจํธ๋กค๋ฌ์์ ์์ฒญ์ ๋ฐ์ ์ฒ๋ฆฌํด์ผ ํ๋ ๋ก์ง(ํ์ ๊ฐ์
, ์๋ฆผ ๋ฐ์ก ๋ฑ)์ด ์๋ค๋ฉด ์ค์ ๋น์ฆ๋์ค ๋ก์ง์ @Service๊ฐ ๋ถ์ ํด๋์ค์์ ๊ตฌํ๋๋ค.
@Service
public class MemberService {
public void registerMember(Member member) {
// ํ์๊ฐ์ ์ฒ๋ฆฌ ๋ก์ง
}
}
@Service ์์ฒด๊ฐ ํน๋ณํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ๊ฒ์ ์๋์ง๋ง ํด๋น ํด๋์ค๊ฐ ๋น์ฆ๋์ค ๊ณ์ธต์ ์ํ๋ค๋ ๊ฒ์ ๋ช
ํํ๊ฒ ํํํ๋ ์ญํ ์ ํ๋ค. ์ด๋ฅผ ํตํด ์ฝ๋์ ๊ตฌ์กฐ๋ฅผ ์ดํดํ๊ธฐ ์ฌ์์ง๊ณ ์ ์ง๋ณด์์๋ ๋์์ด ๋๋ค.
๋ํ AOP๋ฅผ ์ ์ฉํ ๋ @Service๊ฐ ๋ถ์ ํด๋์ค๋ง์ ๋์์ผ๋ก ์ง์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ก๊น
์ด๋ ํธ๋์ญ์
๊ด๋ฆฌ์ ๊ฐ์ ๊ณตํต ๊ธฐ๋ฅ์ ์ ์ฉํ ๋๋ ์ ์ฉํ๊ฒ ํ์ฉ๋๋ค.
@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๋ฅผ ์ง์ ์ฌ์ฉํ ๋ ๋ ์๋ฏธ ์๊ฒ ์์ฉํ๋ค.
