- IoC
- ์ฐธ๊ณ ์๋ฃ
์ ์ด์ ์ญ์ (Inversion of Control)?
- ๋ ์์ ์ด ์ ์ด๊ถ์ ๊ฐ์ง๊ณ ์์ง x, ๋ ์ด์ธ์ ๋๊ตฐ๊ฐ๊ฐ ์์กด์ฑ์ ๋ํ ์ ์ด๊ถ์ ๊ฐ์ง๊ณ ์๋ค.
- ์ด๋ค ๊ฐ์ฒด๊ฐ ์ฌ์ฉํ๋ ์์กด ๊ฐ์ฒด๋ฅผ ์ง์ ๋ง๋ค์ด์ ์ฌ์ฉํ๋๊ฒ ์๋๋ผ ์ฃผ์ ๋ฐ์์ ์ฌ์ฉํ๋ ๊ฒ์ ๋งํ๋ค.
"๋ด๊ฐ ์ธ ๋์ ๋ด๊ฐ ๋ง๋ค์ด ์ธ๊ฒ"
class OwnerController {
private OwnerRepository repository = new OwnerRepository();
}
- OwnerController๊ฐ OwnerRepository๋ฅผ ์์ฑํ๋ค.
- ์์กด์ฑ์ ๋ํ ์ ์ด๊ถ => ๋ณธ์ธ(OwnerController)
"๋ด๊ฐ ์ธ ๋์ ์ด ๋์ธ๋ฐ... ๋๊ตฐ๊ฐ ์์์ ์ฃผ๊ฒ ์ง"
class OwnerController {
private OwnerRepository repo;
public OwnerController (OwnerRepository repo) {
this.repo = repo;
}
}
- OwnerController๊ฐ ์์ฑ๋ ๋ ๋๊ตฐ๊ฐ๊ฐ OwnerRepository ๊ฐ์ฒด๋ฅผ ์ค๋ค.
- ์์กด์ฑ์ ๋ํ ์ ์ด๊ถ => ๋๊ตฐ๊ฐ(IoC Container)
class OwnerControllerTest {
public void create() {
OwnerRepository repo = new OwnerRepository ();
OwnerController controller = new OwnerController(repo);
}
}
- OwnerControllerTest๊ฐ OwnerRepository๋ฅผ ์์ฑํด์ ์ด๋ฅผ OwnerController์ ์ฃผ์
ํด์ค๋ค.
- ์์กด์ฑ์ ๋ํ ์ ์ด๊ถ => OwnerControllerTest
- ์ ์ด๊ถ์ ์์ ์ด ์๋ ๋ณ๋์ IoC ์ปจํ ์ด๋์๊ฒ ๋๊น์ผ๋ก์ ๊ฐ์ฒด๊ฐ ์์ ์ด ์ฌ์ฉํ ๋์์ ์์ฑ์ด๋ ์ ํ์ ๊ดํ ์ฑ ์์ผ๋ก๋ถํฐ ์์ ๋ก์์ง๋ค.
- ์ธํฐํ์ด์ค ๊ธฐ๋ฐ์ผ๋ก ๊น๋ํ ์ค๊ณ๊ฐ ๊ฐ๋ฅํ๊ณ ์ ์ฐ์ฑ์ด ์ฆ๊ฐํ๋ฉฐ, ํ์ฅ์ฑ์ด ์ข์์ง๋ค.
์คํ๋ง์์๋ ApplicationContext๋ฅผ IoC ์ปจํ ์ด๋๋ผ๊ณ ํ๋ค. ๊ฐ๋จํ Spring ์ปจํ ์ด๋๋ผ๊ณ ํ๋ค.
public interface ApplicationContext
extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
//...
}
BeanFactory
: ๋น ์์ฑ ๋ฐ ์์กด์ฑ ๊ด๋ฆฌ(ListableBeanFactory, HierarchicalBeanFactory)MessageSource
: ๋ฉ์์ง ์์ค ์ฒ๋ฆฌ ๊ธฐ๋ฅ(i18n)ApplicationEventPublisher
: ์ด๋ฒคํธ ๋ฐํ ๊ธฐ๋ฅResourceLoader
: ๋ฆฌ์์ค ๋ก๋ฉ ๊ธฐ๋ฅ (ResourcePatternResolver)
์คํ๋ง IoC ์ปจํ ์ด๋๊ฐ ๊ด๋ฆฌํ๋ ๊ฐ์ฒด๋ฅผ ๋น(bean)์ด๋ผ๊ณ ํ๋ค. ๋ฐ๋ผ์ IoC ์ปจํ ์ด๋์ ๋ฑ๋กํ์ง ์์ ๊ฐ์ฒด๋ ์คํ๋ง ๋น์ด๋ผ๊ณ ํ ์ ์๋ค.
- ์์
- OwnerController(
@Controller
), OwnerService(@Service
), OwnerRepository(@Repository
)๋ IoC ์ปจํ ์ด๋์์ ๊ด๋ฆฌํ๋ ๋น(bean)์ด๋ค. - Owner(Entity๋ก์์ Owner)๋ ๋น(bean)์ด ์๋๋ค.
- OwnerController(
๋น์ ๋ํ ์ ์๋ฅผ ๋ด๊ณ ์๋ค.
- ์ด๋ฆ ๋๋ id
- ํด๋์ค
- ์ค์ฝํ
- ์์ฑ์ ์๊ท๋จผํธ(construct)
- ํ๋กํผํฐ(setter)
- ๋ฑ๋ฑ
- ์์กด์ฑ ๊ด๋ฆฌ
- ์ค์ฝํ
- ์ฑ๊ธํค : ํ๋
- ํ๋กํ ํ์ : ๋งค๋ฒ ๋ค๋ฅธ ๊ฐ์ฒด
- ๋ผ์ดํ์ฌ์ดํด ์ธํฐํ์ด์ค : ๋น์ด ๋ง๋ค์ด์ก์ ๋ ๋ถ๊ฐ์์ ์ ํ๊ณ ์ถ์ ๊ฒฝ์ฐ ์ฌ์ฉํ๋ค.
/* ์ด๊ธฐํ ๋ฉ์๋. ๋น์ด ์์ฑ๋๊ณ DI ์์
์ ๋ง์น๋ค์ ์คํ๋๋ค. */
@PostConstruct
public void postConstruct() {
System.out.println("=================");
System.out.println("Hello");
}
์คํ๋ง์ ์คํ๋ง IoC ์ปจํ ์ด๋์ ์คํ๋ง ๋น์ ๋ฑ๋กํ ๋, ๊ธฐ๋ณธ์ผ๋ก ์ฑ๊ธํค์ผ๋ก ๋ฑ๋กํ๋ค.(์ ์ผํ๊ฒ ํ๋๋ง ๋ฑ๋กํด์ ๊ณต์ ) ๋ฐ๋ผ์ ๊ฐ์ ์คํ๋ง ๋น์ด๋ฉด ๋ชจ๋ ๊ฐ์ ์ธ์คํด์ค๋ค. ์ค์ ์ผ๋ก ์ฑ๊ธํค์ด ์๋๊ฒ ์ค์ ํ ์ ์์ง๋ง, ํน๋ณํ ๊ฒฝ์ฐ๋ฅผ ์ ์ธํ๋ฉด ๋๋ถ๋ถ ์ฑ๊ธํค์ ์ฌ์ฉํ๋ค.
- Component Scanning
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
// ...
}
์คํ๋ง ๋ถํธ์์๋ @SpringBootApplication
๋ผ๋ ์ ๋
ธํ
์ด์
์ ์ฌ์ฉํ๋๋ฐ ์ด ์ ๋
ธํ
์ด์
์์ ์ปดํฌ๋ํธ ์ค์บ์ ํ ์ ์๋ @ComponentScan
์ด ์๋ค.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
// ...
}
@ComponentScan
์ ์ค์บํ ํจํค์ง์ ์ ๋
ธํ
์ด์
์ ๋ํ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ค. ์ค์ ์ค์บ๋์ ConfigurationClassPostProcessor๋ผ๋ BeanFactoryPostProcesser์ ์ํด ์ฒ๋ฆฌ๋๋ค.
@Component
: ์ด ์ ๋ ธํ ์ด์ ์ด ์์ผ๋ฉด ์ปดํฌ๋ํธ ์ค์บ์ ํตํด ์คํ๋ง ๋น์ผ๋ก ์๋ ๋ฑ๋ก๋๋ค. ์๋ ์ ๋ ธํ ์ด์ ๋ค์@Component
๋ฅผ ํ์ฅํ๊ธฐ ๋๋ฌธ์ ์ปดํฌ๋ํธ ์ค์บ ๋์์ด ๋๋ค.@Repository
@Service
@Controller
/* Component Scan ๋ฐฉ์์ผ๋ก ์คํ๋ง ๋น(MemberService) ๋ฑ๋ก */
@Service
public class MemberService {
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
- ์ง์ xml์ด๋ ์๋ฐ ์ค์ ํ์ผ์ ๋ฑ๋ก
- xml ์ค์ ๋ฐฉ์์ ์ต๊ทผ์๋ ์ ์ฌ์ฉํ์ง ์๋๋ค.
- ์๋ฐ ์ค์ ํ์ผ์์ ๋น ๋ฑ๋ก์
@Bean
์ ๋ ธํ ์ด์ ์ ๋ถ์ฌ์ผํ๋ค.@Bean
์@Configuration
์์ ์ ์ํด์ผ ํ๋ค.
/* ์๋ฐ ์ค์ ํ์ผ๋ก ์คํ๋ง ๋น(MemberService) ๋ฑ๋ก */
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
์ค๋ฌด์์๋ ์ฃผ๋ก ์ ํํ๋ ์ปจํธ๋กค๋ฌ, ์๋น์ค, ๋ฆฌํฌ์งํ ๋ฆฌ** ๊ฐ์ ์ฝ๋๋ ์ปดํฌ๋ํธ ์ค์บ์ ์ฌ์ฉํ๋ค. ์ ํํ๋์ง ์๊ฑฐ๋, ์ํฉ์ ๋ฐ๋ผ ๊ตฌํ ํด๋์ค๋ฅผ ๋ณ๊ฒฝํด์ผ ํ๋ฉด ์ค์ ์ ํตํด ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๋ค.
@Autowired
IoC ์ปจํ ์ด๋๊ฐ ์ฐ๊ด๋ ๊ฐ์ฒด๋ฅผ ์ฐพ์์ ๋ฉ์๋๋ ์์ฑ์๋ฅผ ํตํด ์ฃผ์ ํด์ค๋ค. (์๋์ )- ๊ฐ์ฒด ์์กด๊ด๊ณ๋ฅผ ์ธ๋ถ์์ ๋ฃ์ด์ฃผ๋ ๊ฒ => DI(Dependency Injection), ์์กด๊ด๊ณ ์ฃผ์
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
ApplicationContext
์getBean()
IoC ์ปจํ ์ด๋์๊ฒ ์ฐ๊ด๋ ๊ฐ์ฒด๋ฅผ ์์ฒญํด์ ๋ฐ๋๋ค. (๋ฅ๋์ )- ๊ฐ์ฒด ์์กด๊ด๊ณ๋ฅผ ์ค์ค๋ก ๊ฒ์ํด์ ๋ฃ์ด์ฃผ๋ ๊ฒ => DL(Dependency Lookup),์์กด๊ด๊ณ ๊ฒ์
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
MemberService memberService = ctx.getBean(MemberService.class);
}
์ด๋ค ๋น์
-
- ์์ฑ์๊ฐ ์ค์ง ํ๋๋ง ์๊ณ
-
- ํ๋ผ๋ฏธํฐ๋ก ๋ฐ๋ ํ์
(๋งค๊ฐ๋ณ์ ํ์
)์ ๋น์ด ์กด์ฌํ๋ค๋ฉด
@Autowired
์ ๋ ธํ ์ด์ ์ ์๋ตํด๋ ์์กด์ฑ์ ์ฃผ์ ํด์ค๋ค. (์คํ๋ง 4.3)
- ํ๋ผ๋ฏธํฐ๋ก ๋ฐ๋ ํ์
(๋งค๊ฐ๋ณ์ ํ์
)์ ๋น์ด ์กด์ฌํ๋ค๋ฉด
public class MemberService {
private final MemberRepository memberRepository;
//@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
@Autowired๋ฅผ ํตํ DI๋ ์คํ๋ง์ด ๊ด๋ฆฌํ๋ ๊ฐ์ฒด(๋น)์์๋ง ๋์ํ๋ค. ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ์ง ์๊ณ ๋ด๊ฐ ์ง์ ์์ฑํ ๊ฐ์ฒด์์๋ ๋์ํ์ง ์๋๋ค.
- ์์ฑ์
- ์ด ํด๋์ค์ ๋ฐ๋์ ํ์ํ ๊ฐ์ฒด๋ค => ์์ฑ์
- ์์กด๊ด๊ณ๊ฐ ์คํ์ค์ ๋์ ์ผ๋ก ๋ณํ๋ ๊ฒฝ์ฐ๋ ๊ฑฐ์ ์์ผ๋ฏ๋ก ์์ฑ์ ์ฃผ์ ์ ๊ถ์ฅํ๋ค.
- ํ๋
- Setter๊ฐ ์๋ค => ํ๋
- Setter
- Setter๊ฐ ์๋ค => Setter
- ์คํ๋ง ํ๋ ์์ํฌ ์ ๋ฌธ
- ์คํ๋ง ์ ๋ฌธ - ์ฝ๋๋ก ๋ฐฐ์ฐ๋ ์คํ๋ง ๋ถํธ, ์น MVC, DB ์ ๊ทผ ๊ธฐ์