๐กDI(Dependency Injection)
IoC๋ผ๋ ์์น์ ๊ตฌํํ๊ธฐ ์ํด์ ์ฌ์ฉ๋๋ ๋ฐฉ๋ฒ ์ค ํ๋๋ก, ์ฉ์ด๋ฅผ ์๋ ๊ทธ๋๋ก ๋ฒ์ญํ๋ฉด `์์กด์ฑ ์ฃผ์ `์ ๋๋ค.
๋ค์์ ์์ ์ฝ๋๋ฅผ ๋ณด๋ฉด
์ค์ MemberService๋ผ๋ ๊ฐ์ฒด์์ MemberRepository๋ผ๋ ๊ฐ์ฒด์ ์์กด์ฑ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
๋, ์๋์ ๊ตฌํ๋ ์ธ๊ฐ์ง ๋ฉ์๋๋ค์ ๋ชจ๋ MemberRepository๊ฐ์ฒด์์ ๊ตฌํํ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
์ด๋ฌํ ์ํฉ์์ MemberRepository๋ผ๋ ๊ฐ์ฒด๋ฅผ ๋ค๋ฅธ MockRepository ๊ฐ์ฒด๋ก ๊ต์ฒดํด์ผ ํ ๊ฒฝ์ฐ ์ด๋ค ์ผ์ด ์ผ์ด๋ ๊น์?
์ค์ ๋ก private final MemberRepository memberRepository = new MockRepository();๋ก ๋ณ๊ฒฝํ๋ฉด ๋ ๊น์?
์ด๋ ๊ฒ ๊ฐ์ฒด๋ฅผ ์ง์ ๋ณ๊ฒฝํ๋ฉด ์๋์ ๊ตฌํํ ๋ฉ์๋๋ค๋ ๋ชจ๋ ๋ณ๊ฒฝ๋์ด์ผ ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฐ์ฒด ๊ฐ์ ๊ด๊ณ๊ฐ ๋ณ๊ฒฝ๋ ๋๋ค๋ง ์ฐ๋ฆฌ๊ฐ ์ง์ ํด๋น ์ฝ๋๋ฅผ ์ฐพ์ ์์ ํ๊ณ ๋ฌธ์ ์ ์ด ์๋์ง ์ดํด๋ณด๋ ๊ณผ์ ์ ๊ฑฐ์ณ์ผ ํฉ๋๋ค. ์ด๋ ๊ฒ ๋ฐ์ํ๋ ๋ฌธ์ ์ ๋ค์ ์์กด์ฑ ์ฃผ์ ์ ํตํด ํด๊ฒฐ์ด ๊ฐ๋ฅํ๋ฐ์.
์ ๊ทธ๋ฆผ์์ ์์ฑ๋ ์ฝ๋์ ๊ฐ์ด ์์ฑ์๋ฅผ ํตํด ์์กด์ฑ์ ์ฃผ์ ๋ฐ์์ผ๋ก์จ ์ฐ๋ฆฌ๋ ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ ์๊ฐ ์์กด๊ด๊ณ๋ฅผ ์ฃผ์ ํ ์ ์์ต๋๋ค. ์์ ๊ฐ์ด ์์ ํ๋ฉด MemberService ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ ์ง์ ํด๋น ํ์ผ์์ MemberRepository ๊ฐ์ฒด๋ฅผ ์์ฑํด ์์ฑ์๋ฅผ ํตํด ๋ฃ์ด์ฃผ์ด์ผ ํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋๋ง๋ค ๊ฒฐ๊ตญ ์ง์ ์ฃผ์ ํ ๊ฐ์ฒด๋ฅผ ์ฐ๋ฆฌ๊ฐ ์์ฑํด์ผ ํฉ๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์ผ์ฐจ์ ์ธ ๋ฐฉ๋ฒ์ผ๋ก๋ ๋ค์๊ณผ ๊ฐ์ด ์์กด์ฑ ์ฃผ์ ์ ๊ด๋ฆฌํ๋ ์ค์ ํ์ผ์ ๋ง๋ค์ด ๊ด์ฌ์ฌ ๋ถ๋ฆฌ๋ฅผ ํตํด ํด๊ฒฐํ ์ ์์ต๋๋ค.
package com.codestates;
import com.codestates.coffee.CoffeeRepository;
import com.codestates.coffee.CoffeeService;
import com.codestates.member.MemberRepository;
import com.codestates.member.MemberService;
//์์กด์ฑ ์ค์ ํ์ผ
public class DependencyConfig {
public MemberService memberService(){
return new MemberService(memberRepository());
}
public MemberRepository memberRepository(){
return new MemberRepository();
}
public CoffeeService coffeeService(){
return new CoffeeService(coffeeRepository());
}
public CoffeeRepository coffeeRepository(){
return new CoffeeRepository();
}
}
์ด๋ ๊ฒ ์ญํ ์ ๋ช ํํ ๋๋์ด ์์ฑํด์ค๋ค๋ฉด ๋ ์ด์ ์๋น์ค ๋ด๋ถ์์ ๊ฐ์ฒด ์ฃผ์ ๊ด๋ จํด์ ์ฝ๋๋ฅผ ์์ ํ์ง ์๊ณ , DependencyConfig.java์์ ๊ตฌํ ๋ถ๋ถ๋ง ์์ ํด์ฃผ๋ฉด ๋ฉ๋๋ค.
์ฆ, MemberService, CoffeeService๋ ์์ฑ์๋ฅผ ํตํด ์ด๋ค ๊ตฌํ ๊ฐ์ฒด๊ฐ ์ฃผ์ ๋๋์ง ์ ํ์๊ฐ ์๊ณ ์ค๋ก์ง ์คํ์๋ง ์ง์คํ๋ฉด ๋ฉ๋๋ค.
์ด๋ ๊ฒ ์ฐ๋ฆฌ๋ ์ง์ ์ค์ ํ์ผ์ ํตํด ์์กด์ฑ ์ฃผ์ ์ ํ ์ ์์ต๋๋ค.
ํ์ง๋ง, ์คํ๋ง ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ๋ฉด ์ง์ ์ค์ ํ์ผ์ ๋ง๋ค์ง ์์๋ ์์กด์ฑ ์ฃผ์ ์ด ๊ฐ๋ฅํฉ๋๋ค.
๐ก์คํ๋ง ์ปจํ ์ด๋๋?
์คํ๋ง ์ปจํ ์ด๋๋ ์คํ๋ง ํ๋ ์์ํฌ์ ํต์ฌ ์ปดํฌ๋ํธ๋ก, ์คํ๋ง ์ปจํ ์ด๋ ๋ด๋ถ์ ์กด์ฌํ๋ ์ ํ๋ฆฌ์ผ์ด์ ๋น์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค.
๋ณดํต AppllicatioinContext๋ฅผ ์คํ๋ง ์ปจํ ์ด๋๋ผ๊ณ ํ๋ฉฐ, ApplicationContext๋ ์ธํฐํ์ด์ค๋ก ๊ตฌํ๋์ด ์์ต๋๋ค.
ApplicationContext (Spring Framework 6.0.7 API)
Expose AutowireCapableBeanFactory functionality for this context. This is not typically used by application code, except for the purpose of initializing bean instances that live outside the application context, applying the Spring bean lifecycle (fully or
docs.spring.io
์คํ๋ง ์ปจํ ์ด๋๋ XML, ์ ๋ํ ์ด์ ๊ธฐ๋ฐ์ ์๋ฐ ์ค์ ํด๋์ค๋ก ๋ง๋ค ์ ์์ผ๋ฉฐ, ์์ ์๋ ๊ฐ๋ฐ์๊ฐ xml์ ํตํด ๋ชจ๋ ์ค์ ํด์คฌ์ผ๋ ์ด๋ฌํ ๋ณต์กํ ๋ถ๋ถ๋ค์ Spring Boot๋ฅผ ์ฌ์ฉํ๋ฉด์ ๊ฑฐ์ ์ฌ์ฉํ์ง ์๊ฒ ๋์์ต๋๋ค. ์คํ๋ง ์ปจํ ์ด๋๋ DI๋ฅผ ํตํด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ปดํฌ๋ํธ๋ฅผ ๊ด๋ฆฌํ๋ฉฐ, ์๋ก ๋ค๋ฅธ ๋น์ ์ฐ๊ฒฐํด ์ ํ๋ฆฌ์ผ์ด์ ์ ๋น์ ์ฐ๊ฒฐํ๋ ์ญํ ์ ํฉ๋๋ค.
์ ์คํ๋ง ์ปจํ ์ด๋๋ฅผ ์ฌ์ฉํ ๊น?
๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด new ์์ฑ์๋ฅผ ์จ์ผ ํ์๋๋ฐ, ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ด๋ฌํ ๊ฐ์ฒด๊ฐ ๋ฌด์ํ ๋ง์ด ์กด์ฌํ๊ณ ์๋ก ์ฐธ์กฐํ๊ฒ ๋์ด์์ผ๋ฉด, ๊ฐ์ฒด ๊ฐ์ ์์กด์ฑ์ด ๋์์ง๊ณ (ํด๋์ค ๊ฐ ๊ฐํ ๊ฒฐํฉ) ๊ทธ๋ ๊ฒ ๋๋ฉด ๊ฐ์ฒด์งํฅํ๋ก๊ทธ๋๋ฐ์ ํต์ฌ ์ค ํ๋์ธ ๋ฎ์ ๊ฒฐํฉ๋์ ๋์ ์บก์ ํ๊ฐ ์ง์ผ์ง์ง ๋ชปํ๊ฒ ๋ฉ๋๋ค. ๋ฐ๋ผ์ ๊ฐ์ฒด ๊ฐ์ ์์กด์ฑ์ ๋ฎ์ถ๊ธฐ ์ํด ์คํ๋ง ์ปจํ ์ด๋๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์คํ๋ง ์ปจํ ์ด๋์ ์์ฑ ๊ณผ์
์คํ๋ง ์ปจํ ์ด๋๋ ํ๋ผ๋ฏธํฐ๋ก ๋์ด์จ Configuration Metatdata๋ฅผ ์ฌ์ฉํด์ ์คํ๋ง ๋น์ ๋ฑ๋กํฉ๋๋ค.
// Spring Container ์์ฑ
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(DependencyConfig.class);
์ ์ฝ๋๋ ์ ๋ํ ์ด์ ๊ธฐ๋ฐ์ ์๋ฐ ์ค์ ํด๋์ค๋ก Spring Container๋ฅผ ๋ง๋๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
XML ๊ธฐ๋ฐ์ผ๋ก ๋ง๋๋ 'ClassPathXmlApplicationContext'๋ ์์ต๋๋ค.
ApplicationContext ์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด๋ฅผ ํตํด ๋ค์ํ๊ฒ ์คํ๋ง ์ปจํ ์ด๋๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
์คํ๋ง ์ปจํ ์ด๋์ ์ข ๋ฅ
์ค๋ธ์ ํธ์ ์์ฑ๊ณผ ์ค๋ธ์ ํธ ์ฌ์์ ๋ฐํ์ ๊ด๊ณ๋ฅผ ์ค์ ํ๋ DI ๊ด์ ์ผ๋ก ๋ณผ ๋๋ ์คํ๋ง ์ปจํ ์ด๋๋ฅผ BeanFactory๋ผ ํ๊ณ , DI๋ฅผ ์ํ BeanFactory์ ์ํฐํ๋ผ์ด์ฆ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ๋ ๋ฐ ํ์ํ ์ฌ๋ฌ ๊ฐ์ง ์ปจํ ์ด๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ๊ฒ์ ApplicationContext๋ผ๊ณ ํฉ๋๋ค.
BeanFactory : ์คํ๋ง ์ปจํ ์ด๋์ ์ต์์ ํด๋์ค๋ก ๋น์ ๋ฑ๋กํ๊ณ ์์ฑํ๊ณ ์กฐํํ๊ณ ๋๋ ค์ฃผ๋ ๋ฑ ๋น์ ๊ด๋ฆฌํ๋ ์ญํ ์ ํฉ๋๋ค. getBean() ๋ฉ์๋๋ฅผ ํตํด ๋น์ ์ธ์คํด์คํํ ์ ์์ผ๋ฉฐ, @Bean์ด ๋ถ์ ๋ฉ์๋์ ๋ช ์ ์คํ๋ง ๋น์ ์ด๋ฆ์ผ๋ก ์ฌ์ฉํด ๋น๋ฑ๋ก์ ํฉ๋๋ค.
ApplicationContext : BeanFactory์ ๊ธฐ๋ฅ์ ์์๋ฐ์ ์ ๊ณตํ๋ฉฐ, ๋น์ ๊ด๋ฆฌํ๊ณ ๊ฒ์ํ๋ ๊ธฐ๋ฅ์ BeanFactory๊ฐ ์ ๊ณตํ๊ณ ๊ทธ ์ธ ๋ถ๊ฐ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
ApplicationContext๊ฐ ์ ๊ณตํ๋ ๋ถ๊ฐ ๊ธฐ๋ฅ
- MessageSource : ๋ฉ์์ง ๋ค๊ตญํ๋ฅผ ์ํ ์ธํฐํ์ด์ค
- EnvironmentCapable : ๊ฐ๋ฐ, ์ด์ ๋ฑ ํ๊ฒฝ๋ณ์ ๋ฑ์ผ๋ก ๋๋ ์ฒ๋ฆฌํ๊ณ , ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ๋ ์ ํ์ํ ์ ๋ณด๋ค์ ๊ด๋ฆฌํ๊ธฐ ์ํ ์ธํฐํ์ด์ค
- ApplicationEventPublisher : ์ด๋ฒคํธ ๊ด๋ จ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ์ธํฐํ์ด์ค
- ResourceLoader : ํ์ผ, ํด๋์ค ํจ์ค, ์ธ๋ถ ๋ฑ ๋ฆฌ์์ค๋ฅผ ํธ๋ฆฌํ๊ฒ ์กฐํ
๐ก๋น(Bean)
์คํ๋ง ์ปจํ ์ด๋์ ์ํด ๊ด๋ฆฌ๋๋ ์ฌ์ฌ์ฉ ์ํํธ์จ์ด ์ปดํฌ๋ํธ๋ก Spring ์ปจํ ์ด๋๊ฐ ๊ด๋ฆฌํ๋ ์๋ฐ ๊ฐ์ฒด๋ฅผ ์๋ฏธํ๋ฉฐ, ์คํ๋ง ์ปจํ ์ด๋๋ ํ๋ ์ด์์ ๋น์ ๊ด๋ฆฌํฉ๋๋ค.
๋น์ ์ธ์คํด์คํ๋ ๊ฐ์ฒด๋ฅผ ์๋ฏธํ๋ฉฐ, ์คํ๋ง ์ปจํ ์ด๋์ ๋ฑ๋ก๋ ๊ฐ์ฒด๋ฅผ ์คํ๋ง ๋น์ด๋ผ๊ณ ํฉ๋๋ค.
@Bean์ด ์ ํ ๋ฉ์๋๋ฅผ ๋ชจ๋ ํธ์ถํด์ ๋ฐํ๋ ๊ฐ์ฒด๋ฅผ ์คํ๋ง ์ปจํ ์ด๋์ ๋ฑ๋กํฉ๋๋ค.
๋น์ ํด๋์ค์ ๋ฑ๋ก ์ ๋ณด, getter/setter ๋ฉ์๋๋ฅผ ํฌํจํ๋ฉฐ, ์ปจํ ์ด๋์ ์ฌ์ฉ๋๋ ์ค์ ๋ฉํ๋ฐ์ดํฐ๋ก ์์ฑ๋ฉ๋๋ค.
์ค์ ๋ฉํ ๋ฐ์ดํฐ๋ XML ๋๋ ์๋ฐ ์ ๋ํ ์ด์ , ์๋ฐ์ฝ๋๋ก ํํํ๋ฉฐ, ์ปจํ ์ด๋์ ๋ช ๋ น๊ณผ ์ธ์คํด์คํ, ์ค์ , ์กฐ๋ฆฝํ ๊ฐ์ฒด๋ฅผ ์ ์ํฉ๋๋ค.
bean ์ ๊ทผ ๋ฐฉ๋ฒ
AppicationContext๋ฅผ ์ฌ์ฉํ์ฌ bean ์ ์๋ฅผ ์ฝ๊ณ ์ก์ธ์ค ๊ฐ๋ฅํฉ๋๋ค.
// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
// retrieve configured instance
PetStoreService service = context.getBean("memberRepository", memberRepository.class);
// use configured instance
List<String> userList = service.getUsernameList();
BeanDefinition
Bean์ BeanDefinition(๋น ์ค์ ๋ฉํ์ ๋ณด)๋ก ์ ์๋๊ณ , BeanDefinition์ ๋ฐ๋ผ์ ํ์ฉํ ์ ์๋ ๋ฐฉ๋ฒ์ด ๋ฌ๋ผ์ง๊ฒ ๋ฉ๋๋ค.
BeanDefinition์ ์์ฑ์ ๋ฐ๋ผ ์ปจํ ์ด๋๊ฐ Bean์ ์ด๋ป๊ฒ ์์ฑํ๊ณ ๊ด๋ฆฌํ ์ง ๊ฒฐ์ ํฉ๋๋ค. @Bean or <bean> ๋น 1๊ฐ์ ๋ฉํ์ ๋ณด๊ฐ ์์ฑ๋ฉ๋๋ค. Spring์ด ์ค์ ๋ฉํ์ ๋ณด๋ฅผ BeanDefinition ์ธํฐํ์ด์ค๋ฅผ ํตํด ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ ์ปจํ ์ด๋ ์ค์ ์ XML, Java๋ก ํ ์ ์๋ ๊ฒ์ ๋๋ค.
ํต์ฌ ์ ๋ฆฌ๐
์คํ๋ง IoC๋ ๊ฐ ๋น์ ๋ํ ์ ๋ณด๋ฅผ ๋ด์ ์ค์ ๋ฉํ์ ๋ณด๋ฅผ ์ฝ์ด๋ค์ธ ๋ค์, ์ด๋ฅผ ์ฐธ๊ณ ํด ๋น ์ค๋ธ์ ํธ๋ฅผ ์์ฑํ๊ณ ํ๋กํผํฐ๋ ์์ฑ์๋ฅผ ํตํด ์์กด ์ค๋ธ์ ํธ๋ฅผ ์ฃผ์ ํด์ฃผ๋ DI ์์ ์ ์ํํฉ๋๋ค. ์ด ์์ ์ ํตํด ๋ง๋ค์ด์ง๊ณ , DI๋ก ์ฐ๊ฒฐ๋ ์ค๋ธ์ ํธ๋ค์ด ๋ชจ์ฌ์ ํ๋์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ฑํ๊ณ ๋์ํ๊ฒ ๋ฉ๋๋ค. ๊ฒฐ๊ตญ, ์คํ๋ง ์ ํ๋ฆฌ์ผ์ด์ ์ด๋ POJO ํด๋์ค์ ์ค์ ๋ฉํ์ ๋ณด๋ฅผ ์ด์ฉํด IoC ์ปจํ ์ด๋๊ฐ ๋ง๋ค์ด์ฃผ๋ ์ค๋ธ์ ํธ์ ์กฐํฉ์ ๋๋ค.
Bean Scope
๋น์ด ์กด์ฌํ ์ ์๋ ๋ฒ์๋ก, ํน์ bean ์ ์์์ ์์ฑ๋ ๊ฐ์ฒด์ ์ฐ๊ฒฐํ ๋ค์ํ ์์กด์ฑ ๋ฐ ๊ตฌ์ฑ ๊ฐ ๋ฟ๋ง ์๋๋ผ ํน์ bean ์ ์์์ ์์ฑ๋ ๊ฐ์ฒด์ ๋ฒ์๋ ์ ์ด ๊ฐ๋ฅํฉ๋๋ค.
์ฑ๊ธํค ์ค์ฝํ
์คํ๋ง ์ปจํ ์ด๋์ ์์๊ณผ ํจ๊ป ์์ฑ๋์ด์ ์คํ๋ง ์ปจํ ์ด๋๊ฐ ์ข ๋ฃ๋ ๋๊น์ง ์ ์ง๋๋ฉฐ, ์ฑ๊ธํค ๋น์ ํ๋์ ๊ณต์ ์ธ์คํด์ค๋ง ๊ด๋ฆฌํ๊ฒ ๋ฉ๋๋ค. (private ์์ฑ์๋ฅผ ์ฌ์ฉํด ์ธ๋ถ์์ ์์๋ก new๋ฅผ ์ฌ์ฉํ์ง ๋ชปํ๋๋ก ๋ง์์ผ ํจ)
ํด๋น bean definition๊ณผ ์ผ์นํ๋ ID ๋๋ ID๋ฅผ ๊ฐ์ง ๋น์ ๋ํ ๋ชจ๋ ์์ฒญ์ ์คํ๋ง ์ปจํ ์ด๋์์ ํด๋น ํน์ ๋น ์ธ์คํด์ค๋ฅผ ๋ฐํํฉ๋๋ค. ์คํ๋ง ์ปจํ ์ด๋ ์ข ๋ฃ ์ ์๋ฉธ ๋ฉ์๋๋ ์๋์ผ๋ก ์คํ๋ฉ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ bean์ scope๊ฐ ๋ช ์์ ์ผ๋ก ์ง์ ๋์ง ์์ผ๋ฉด ์ฑ๊ธํค์ ๋๋ค.
Singleton ์ค์ต
package com.codestates;
import com.codestates.member.MemberService;
public class SingletonTest {
static DependencyConfig dependencyConfig = new DependencyConfig();
static MemberService memberService1 = dependencyConfig.memberService();
static MemberService memberService2 = dependencyConfig.memberService();
public static void main(String[] args) {
System.out.println("memberService1 : " + memberService1);
System.out.println("memberService2 : " + memberService2);
}
}
๊ฐ์ memberService๋ฅผ ์ฌ์ฉํ์ง๋ง ๋ค์ ๋ถ์ ์ฃผ์๊ฐ์ด ๋ค๋ฅธ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ์๋ง์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ฒ ๋๋ฉด ์ ๋ฐฉ์์ ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น์ ํจ์จ์ฑ์ด ๋จ์ด์ง๊ฒ ๋ฉ๋๋ค.
์ฑ๊ธํค ํจํด ์ ์ฉ ์ฝ๋
package com.codestates.singleton;
public class SingletonService {
//1.static ์์ญ์ ๊ฐ์ฒด๋ฅผ 1๊ฐ๋ง ์์ฑ
public static final SingletonService instance = new SingletonService();
//2. ๊ฐ์ฒด ์ธ์คํด์ค๊ฐ ํ์ํ๋ฉด ์๋ public static ๋ฉ์๋๋ฅผ ํตํด์๋ง ์กฐํํ ์ ์๋๋ก ํจ.
public static SingletonService getInstance(){
return instance;
}
//3. ์์ฑ์๋ฅผ private์ ์ ์ธํ์ฌ ์ธ๋ถ์์ new ํค์๋๋ฅผ ํตํด ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์๋๋ก ํจ.
private SingletonService(){
}
}
package com.codestates;
import com.codestates.member.MemberService;
import com.codestates.singleton.SingletonService;
public class SingletonTest {
static SingletonService singletonService1 = SingletonService.getInstance();
static SingletonService singletonService2 = SingletonService.getInstance();
public static void main(String[] args) {
System.out.println("memberService1 : " + singletonService1);
System.out.println("memberService2 : " + singletonService2);
}
}
์ฑ๊ธํค ํจํด์ ๋ฌธ์ ์
์ฑ๊ธํค ํจํด์ ๊ตฌํํ๋ ์ฝ๋ ์์ฒด๊ฐ ๊ธธ๊ณ , ์์กด๊ด๊ณ์ ํด๋ผ์ด์ธํธ๊ฐ ๊ตฌ์ฒด ํด๋์ค์ ์์กดํ๊ฒ ๋ฉ๋๋ค. ๋, private ์์ฑ์๋ฅผ ์ฌ์ฉํ์ฌ ์์ ํด๋์ค๋ฅผ ๋ง๋ค๊ธฐ ์ด๋ ต๊ธฐ ๋๋ฌธ์ ์ ์ฐ์ฑ์ด ๋จ์ด์ง๋๋ค.
์ด๋ฌํ ์ฑ๊ธํค ํจํด ๋ฌธ์ ๋ฅผ ์คํ๋ง ์ปจํ ์ด๋๊ฐ ํด๊ฒฐํด์ค๋๋ค. ์คํ๋ง ์ปจํ ์ด๋๋ ์ฑ๊ธํค ์ปจํ ์ด๋ ์ญํ ์ ํฉ๋๋ค.
- private ์์ฑ์๋ก ๊ฐ์ฒด์ ์์ฑ์ ๋ง๋ ๋ฐฉ๋ฒ์ด ์๋๋ผ ์ผ๋ฐ ์๋ฐ ํด๋์ค๋ฅผ ์ฑ๊ธํค์ผ๋ก ํ์ฉํ ์ ์๋๋ก ์ง์
- ์์ฑ, ๊ด๊ณ ์ค์ , ์ฌ์ฉ์ ๋ํ ์ ์ด๊ถ์ด ์ปจํ ์ด๋์๊ฒ ์๊ธฐ ๋๋ฌธ์ ์ผ๋ฐ ์๋ฐ ํด๋์ค๋ ์ฑ๊ธํค์ผ๋ก ๊ด๋ฆฌ๋ ์ ์์
- public ์์ฑ์๋ฅผ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ํ์ํ๋ค๋ฉด ์๋ก์ด ์ค๋ธ์ ํธ๋ฅผ ์์ฑํ๊ณ , Mock ์ค๋ธ์ ํธ๋ก ๋์ฒดํ๋ ๋ฑ์ ์์ ์ด ๊ฐ๋ฅ.
- ๊ฐ์ฒด์งํฅ์ ์ค๊ณ์ ๋์์ธ ํจํด ์ ์ฉ ๊ฐ๋ฅ
์ด๋ ๊ฒ ์ฑ๊ธํค ๊ฐ์ฒด๋ก ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ ๊ธฐ๋ฅ์ ์ฑ๊ธํค ๋ ์ง์คํธ๋ฆฌ๋ผ๊ณ ํ๋ฉฐ, ์คํ๋ง ์ปจํ ์ด๋์ ๊ธฐ๋ฅ ๋๋ถ์ ์ฑ๊ธํค ํจํด์ ๋ชจ๋ ๋จ์ ์ ํด๊ฒฐํ๋ฉฐ ๊ฐ์ฒด๋ฅผ ์ฑ๊ธํค์ผ๋ก ์ ์ง ๊ฐ๋ฅํฉ๋๋ค.
package com.codestates;
import com.codestates.coffee.CoffeeRepository;
import com.codestates.coffee.CoffeeService;
import com.codestates.member.MemberRepository;
import com.codestates.member.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//์์กด์ฑ ์ค์ ํ์ผ
@Configuration
public class DependencyConfig {
@Bean
public MemberService memberService(){
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository(){
return new MemberRepository();
}
@Bean
public CoffeeService coffeeService(){
return new CoffeeService(coffeeRepository());
}
@Bean
public CoffeeRepository coffeeRepository(){
return new CoffeeRepository();
}
}
package com.codestates;
import com.codestates.member.MemberService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class SingletonTest {
static AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(DependencyConfig.class);
static MemberService memberService1 = ac.getBean("memberService", MemberService.class);
static MemberService memberService2 = ac.getBean("memberService", MemberService.class);
public static void main(String[] args) {
System.out.println("memberService1 : " + memberService1);
System.out.println("memberService2 : " + memberService2);
}
}
์ฑ๊ธํค ๋ฐฉ์ ์ฌ์ฉ์ ์ฃผ์์
์ฑ๊ธํค ๋ฐฉ์์ ์ฌ๋ฌ ํด๋ผ์ด์ธํธ๊ฐ ํ๋์ ๊ฐ์ฒด ์ธ์คํด์ค๋ฅผ ๊ณต์ ํ๊ธฐ ๋๋ฌธ์ ์ฑ๊ธํค ๊ฐ์ฒด๋ ๋ฌด์ํ๋ก ์ค๊ณํด์ผ ํฉ๋๋ค.
ํน์ ํด๋ผ์ด์ธํธ๊ฐ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์์ผ๋ฉด ์๋๋ฉฐ, Read-only์ฌ์ผ ํฉ๋๋ค. ์คํ๋ง ๋น์ ๊ณต์ ๊ฐ์ ์ค์ ํ๋ฉด ์ฅ์ ๊ฐ ๋ฐ์ํ ์ ๋ฐ์ ์์ต๋๋ค.
๐กJava ๊ธฐ๋ฐ Container ์ค์
@Bean๊ณผ @Configuration
//DependencyConfig ํด๋์ค
//์ปจํ
์คํธ๋ฅผ ์ธ์คํด์คํํ ๋
@Configuration
public class DependencyConfig{
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
ApplicationContext ๊ตฌํ์ ์๋์ ๊ฐ์ ์ ๋ํ ์ด์ ์ด ๋ฌ๋ฆฐ ํด๋์ค๋ก ํ๋ผ๋ฏธํฐ๋ฅผ ์ ๋ฌ๋ฐ๊ณ ์์ต๋๋ค.
- @Configuration ํด๋์ค๊ฐ ์ ๋ ฅ์ผ๋ก ์ ๊ณต๋ ๊ฒฝ์ฐ : @Configuration ํด๋์ค ์์ฒด๊ฐ Bean ์ ์๋ก ๋ฑ๋ก๋๋ ํด๋์ค ๋ด์์ ์ ์ธ๋ ๋ชจ๋ @Bean ๋ฉ์๋๋ Bean ์ ์๋ก ๋ฑ๋ก๋ฉ๋๋ค.
- @Component ํด๋์ค์ JSR-330 ํด๋์ค๊ฐ ์ ๊ณต๋ ๊ฒฝ์ฐ : ๋น ์ ์๋ก ๋ฑ๋ก๋๋ฉฐ ํ์ํ ๊ฒฝ์ฐ ํด๋น ํด๋์ค ๋ด์์ @Autowired ๋๋ @Inject์ ๊ฐ์ DI ๋ฉํ๋ฐ์ดํฐ๊ฐ ์ฌ์ฉ๋๋ ๊ฒ์ผ๋ก ๊ฐ์ ํฉ๋๋ค.
์ฝ๋
@Configuration ํด๋์ค๋ฅผ ์ ๋ ฅ์ผ๋ก ์ฌ์ฉํ ๊ฒฝ์ฐ
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(DependencyConfig.class);
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
@Component ๋๋ JSR-330 ์ฃผ์์ด ๋ฌ๋ฆฐ ํด๋์ค๋ ๋ค์๊ณผ ๊ฐ์ด ์์ฑ์์ ์ ๋ ฅ์ผ๋ก ์ฌ์ฉ
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(MyServiceImpl.class, Dependency1.class, Dependency2.class);
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
@Bean ์ ๋ํ ์ด์ ์ฌ์ฉํ๊ธฐ
@Bean์ ๋ฉ์๋์ ์ถ๊ฐํด์ Bean์ผ๋ก ์ ์ํ ์ ์์ต๋๋ค.
@Configuration
public class DependencyConfig {
@Bean
public TransferServiceImpl transferService() {
return new TransferServiceImpl();
}
}
Java ๊ธฐ๋ฐ ์ปจํ ์ด๋ ์ค์
// DependencyConfig.java
package com.codestates.section2week4;
import com.codestates.section2week4.coffee.CoffeeRepository;
import com.codestates.section2week4.coffee.CoffeeService;
import com.codestates.section2week4.member.MemberRepository;
import com.codestates.section2week4.member.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DependencyConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemberRepository();
}
@Bean
public CoffeeService coffeeService() {
return new CoffeeService(coffeeRepository());
}
@Bean
public CoffeeRepository coffeeRepository() {
return new CoffeeRepository();
}
}
๐กComponent Scan
์คํ๋ง์ ์ค์ ์ ๋ณด ์์ด ์๋์ผ๋ก ์คํ๋ง ๋น์ ๋ฑ๋กํ๋ ์ปดํฌ๋ํธ ์ค์บ์ด๋ผ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
์์์๋ ์คํ๋ง ๋น์ ๋ฑ๋กํ ๋ ์๋ฐ ์ฝ๋์ @Bean or XML ๋ฑ์ ์ค์ ์ ๋ณด์ ๋ฑ๋กํ ์คํ๋ง ๋น๋ค์ ์ง์ ์์ฑ์ ํด์ผ ํ์ต๋๋ค. ์ด๋ ๊ฒ ์์์ ์ผ๋ก ๋ฑ๋กํ๊ฒ ๋๋ฉด ์ค์ ์ ๋ณด๋ ์ปค์ง๊ณ , ๋๋ฝํ๋ ๋ฑ ๋ค์ํ ๋ฌธ์ ๊ฐ ๋ฐ์ ๊ฐ๋ฅํฉ๋๋ค.
@ComponentScan์ @Component๊ฐ ๋ถ์ ๋ชจ๋ ํด๋์ค๋ฅผ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํด์ฃผ๊ธฐ ๋๋ฌธ์ ์ค์ ์ ๋ณด์ ๋ถ์ฌ์ฃผ๋ฉด ๋ฉ๋๋ค. (์์กด๊ด๊ณ๋ ์๋์ผ๋ก ์ฃผ์ ํ๋ @Autowired ๊ธฐ๋ฅ๋ ์ ๊ณตํฉ๋๋ค.)
package com.codestates.section2week4;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
@Configuration
@ComponentScan
public class AutoDependencyConfig {
}
๊ธฐ์กด์ ์์ฑํ๋ DependencyConfig์ ๋น๊ตํ๋ค๋ฉด @Bean์ผ๋ก ๋ฑ๋กํ ํด๋์ค๋ฅผ ๋ณผ ์ ์์ต๋๋ค. ๋จ, ComponentScan์ ์ฌ์ฉํ๋ฉด @Configuration์ด ๋ถ์ ์ ๋ณด๋ ์๋์ผ๋ก ๋ฑ๋ก๋ฉ๋๋ค.(Configuration ๋ด๋ถ์ @Component๊ฐ ๋ถ์ด์๊ธฐ ๋๋ฌธ)
@Component, @Autowired ์ถ๊ฐ
@Component๋ @ComponentScan์ด ๋ฑ๋ก๋ ๊ณณ์์ @Component๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
@Autowired๋ ์์ฑ์ ์์กด์ฑ ์ฃผ์ ์ ํ์ํ ์ค์ ์ ๋ณด ๋์ ์์กด๊ด๊ณ ์๋ ์ฃผ์ ์ ํด์ฃผ๊ฒ ๋ฉ๋๋ค.
package com.codestates.section2week4.member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
public void createMember(Member member) {
memberRepository.postMember(member);
}
public Member getMember(Long memberId) {
return memberRepository.getMember(memberId);
}
public void deleteMember(Long memberId) {
memberRepository.deleteMember(memberId);
}
}
package com.codestates.section2week4.coffee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CoffeeService {
private static CoffeeRepository coffeeRepository;
@Autowired
public CoffeeService(CoffeeRepository coffeeRepository) {
this.coffeeRepository = coffeeRepository;
}
public void createCoffee(Coffee coffee) {
coffeeRepository.postCoffee(coffee);
}
public Coffee editCoffee(Long coffeeId, String korName, int price) {
return coffeeRepository.patchCoffee(coffeeId, korName, price);
}
public Coffee getCoffee(Long coffeeId) {
return coffeeRepository.getCoffee(coffeeId);
}
public void deleteCoffee(Long coffeeId) {
coffeeRepository.deleteCoffee(coffeeId);
}
}
package com.codestates.section2week4.member;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class MemberRepository {
private static Map<Long, Member> members = new HashMap<>();
public void postMember(Member member) {
members.put(member.getMemberId(), member);
}
public Member getMember(Long memberId) {
return members.get(memberId);
}
public void deleteMember(Long memberId) {
members.remove(memberId);
}
}
package com.codestates.section2week4.coffee;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class CoffeeRepository {
private static Map<Long, Coffee> drinks = new HashMap<>();
public void postCoffee(Coffee coffee) {
drinks.put(coffee.getCoffeeId(), coffee);
}
public Coffee patchCoffee(Long coffeeId, String korName, int price) {
Coffee drink = drinks.get(coffeeId);
drink.setKorName(korName);
drink.setPrice(price);
return drinks.put(coffeeId, drink);
}
public Coffee getCoffee(Long coffeeId) {
return drinks.get(coffeeId);
}
public void deleteCoffee(Long coffeeId) {
drinks.remove(coffeeId);
}
}
์ปดํฌ๋ํธ ์ค์บ ๊ธฐ๋ณธ ๋์
@Component : ์ปดํฌ๋ํธ ์ค์บ์์ ์ฌ์ฉ๋จ.
@Controller, @RestController : ์คํ๋ง MVC ๋ฐ REST ์ ์ฉ ์ปจํธ๋กค๋ฌ์์ ์ฌ์ฉ๋จ.
@Service : ์คํ๋ง ๋น์ฆ๋์ค ๋ก์ง์์ ์ฌ์ฉ๋จ.
@Repository : ์คํ๋ง์ ๋ฐ์ดํฐ ์ ๊ทผ ๊ณ์ธต์์ ์ฌ์ฉ๋จ.
@Configuration : ์คํ๋ง ์ค์ ์ ๋ณด์์ ์ฌ์ฉ๋จ.(ํด๋น ํด๋์ค์ ์์ค ์ฝ๋์๋ @Component๋ฅผ ํฌํจํ๊ณ ์์)
๐ก๋ค์ํ ์์กด๊ด๊ณ ์ฃผ์ ๋ฐฉ๋ฒ
- ์์ฑ์ ์ฃผ์
- ์์ ์ ์ฃผ์ (setter ์ฃผ์ )
- ํ๋ ์ฃผ์
- ์ผ๋ฐ ๋ฉ์๋ ์ฃผ์
์์ฑ์ ์ฃผ์
์์ฑ์์ @Autowired๋ฅผ ํ๋ฉด ์คํ๋ง ์ปจํ ์ด๋์ @Component๋ก ๋ฑ๋ก๋ ๋น์์ ์์ฑ์์ ํ์ํ ๋น๋ค์ ์ฃผ์ ํฉ๋๋ค.
ํน์ง)
- ์์ฑ์ ํธ์ถ ์์ ์ ๋ฑ 1๋ฒ๋ง ํธ์ถ๋๋ ๊ฒ์ด ๋ณด์ฅ๋จ.
- ๋ถ๋ณ๊ณผ ํ์ ์์กด๊ด๊ณ์ ์ฌ์ฉ๋จ
- ์์ฑ์๊ฐ 1๊ฐ๋ง ์กด์ฌํ๋ ๊ฒฝ์ฐ์๋ @Autowired๋ฅผ ์๋ตํด๋ ์๋ ์ฃผ์ ๋จ
- NullPointerException์ ๋ฐฉ์งํ ์ ์์
- ์ฃผ์ ๋ฐ์ ํ๋๋ฅผ final๋ก ์ ์ธ ๊ฐ๋ฅ
์์ ์ ์ฃผ์ (setter ์ฃผ์ )
setter๋ผ ๋ถ๋ฆฌ๋ ํ๋์ ๊ฐ์ ๋ณ๊ฒฝํ๋ ์์ ์ ๋ฉ์๋๋ฅผ ํตํด์ ์์กด ๊ด๊ณ๋ฅผ ์ฃผ์ ํ๋ ๋ฐฉ๋ฒ
ํน์ง)
- ์ ํ๊ณผ ๋ณ๊ฒฝ ๊ฐ๋ฅ์ฑ์ด ์๋ ์์กด๊ด๊ณ์ ์ฌ์ฉ๋จ.
- ์๋ฐ Bean ํ๋กํผํฐ ๊ท์ฝ์ ์์ ์ ๋ฉ์๋ ๋ฐฉ์์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
@Component
public class CoffeeService {
private MemberRepository memberRepository;
private CoffeeRepository coffeeRepository;
@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Autowired
public void setCoffeeRepository(CoffeeRepository coffeeRepository) {
this.coffeeRepository = coffeeRepository;
}
}
์์ฑ์ ์ฃผ์ ๊ณผ์ ์ฐจ์ด์ ์ ์์ฑ์ ๋์ set ํ๋๋ช ๋ฉ์๋๋ฅผ ์์ฑํ์ฌ ์์กด๊ด๊ณ๋ฅผ ์ฃผ์ ํ๊ฒ ๋๋ค๋ ๊ฒ์ ๋๋ค.
์์ ์์ ๊ฒฝ์ฐ @Autowired๋ฅผ ์ ๋ ฅํ์ง ์์ผ๋ฉด ์คํ๋์ง ์์ต๋๋ค.
์์ฑ์๋ 1๊ฐ์ผ๋ @Autowired๊ฐ ์์ด๋ ์๋์ด ๋๋ ์ด์ ๊ฐ ๋ฌด์?
์คํ๋ง์ด ํด๋น ํด๋์ค ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ๋น์ ๋ฃ์ด์ผ ํ๋๋ฐ ์์ฑํ ๋ ์์ฑ์๋ฅผ ๋ถ๋ฅผ ์ ๋ฐ์ ์์ต๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๋น์ ๋ฑ๋กํ๋ฉด์ ์์กด๊ด๊ณ ์ฃผ์ ๋ ๊ฐ์ด ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค.
ํ๋ ์ฃผ์
ํ๋์ @Autowired ๋ถ์ฌ์ ๋ฐ๋ก ์ฃผ์ ํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
ํน์ง)
- ์ฝ๋๊ฐ ๊ฐ๊ฒฐํด์ ์์ ์ ๋ง์ด ์ฌ์ฉ๋ ๋ฐฉ์์ด๋, ์ธ๋ถ์์ ๋ณ๊ฒฝ์ด ๋ถ๊ฐ๋ฅํ์ฌ ํ ์คํธํ๊ธฐ ํ๋ค๋ค๋ ๋จ์ ์ด ์์ต๋๋ค.
- DI ํ๋ ์์ํฌ๊ฐ ์์ผ๋ฉด ์๋ฌด๊ฒ๋ ํ ์ ์์ต๋๋ค.
- ์ค์ ์ฝ๋์ ์๊ด์๋ ํน์ ํ ์คํธ๋ฅผ ํ๊ณ ์ถ์ ๋ ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.
- ์ ์์ ์ผ๋ก ์๋๋๊ฒ ํ๋ ค๋ฉด ๊ฒฐ๊ตญ setter๊ฐ ํ์ํด ์์ ์ ์ฃผ์ ์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ํธ๋ฆฌํฉ๋๋ค.
@Component
public class CoffeeService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private CoffeeRepository coffeeRepository;
}
์ผ๋ฐ ๋ฉ์๋ ์ฃผ์
๋ง๊ทธ๋๋ก ์ผ๋ฐ ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ์ฃผ์ ํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
ํน์ง)
- ํ๋ฒ์ ์ฌ๋ฌ ํ๋๋ฅผ ์ฃผ์ ๋ฐ์ ์ ์์ต๋๋ค.
- ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ๋์ง ์์ต๋๋ค.
package com.codestates;
import com.codestates.member.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.lang.Nullable;
import java.util.Optional;
public class AutowiredTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(TestBean.class);
}
static class TestBean{
@Autowired(required=false) //์๋ ์ฃผ์
ํ ๋์์ด ์์ผ๋ฉด ์์ ์ ๋ฉ์๋ ์์ฒด๊ฐ ํธ์ถ๋์ง ์์.
public void setNoBean1(Member noBean1){
System.out.println("noBean1 = "+noBean1);
}
@Autowired
public void setNoBean2(@Nullable Member noBean2){//์๋ ์ฃผ์
ํ ๋์์ด ์์ผ๋ฉด null์ด ์
๋ ฅ๋จ.
System.out.println("noBean2 = " + noBean2);
}
@Autowired
public void setNoBean3(Optional<Member> noBean3){//Optinoal.emty๊ฐ ์
๋ ฅ๋จ.
System.out.println("noBean3 = " + noBean3);
}
}
}
์์ฑ์ ์ฃผ์ ์ ์ฌ์ฉํด์ผ ํ๋ ์ด์
- ๋ถ๋ณ
- ์์กด๊ด๊ณ ์ฃผ์ ์ ์ฒ์ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์คํ๋ ๋ ๋๋ถ๋ถ ์ ํด์ง๊ณ , ์ข ๋ฃ ์ ๊น์ง ๋ณ๊ฒฝ๋์ง ์๊ณ ๋ณ๊ฒฝ๋์ด์๋ ์๋จ.
- ์์ ์ ์ฃผ์ ๊ฐ์ ๊ฒฝ์ฐ์๋ ์ด๋ฆ ๋ฉ์๋๋ฅผ public์ผ๋ก ์ด์ด๋์ด ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ์ ํฉํ์ง ์์.
- ๋๊ตฐ๊ฐ ์ค์๋ก ๋ณ๊ฒฝํ ์๋ ์๊ณ , ์ ์ด์ ๋ณ๊ฒฝํ๋ฉด ์๋๋ ๋ฉ์๋๊ฐ ๋ณ๊ฒฝํ ์ ์๊ฒ ์ค๊ณํ๋ ๊ฒ์ ์ข์ ๋ฐฉ๋ฒ์ด ์๋.
- ์์ฑ์ ์ฃผ์ ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ ์ต์ด๋ก 1๋ฒ๋ง ํธ์ถ๋๊ณ ๊ทธ ์ดํ์๋ ๋ค์๋ ํธ์ถ๋๋ ์ผ์ด ์๊ธฐ ๋๋ฌธ์ ๋ถ๋ณํ๊ฒ ์ค๊ณํ ์ ์์.
- ๋๋ฝ
- ํธ์ถํ์ ๋๋ NPE(Null Pointer Excpetion)์ด ๋ฐ์ํ๋๋ฐ ์์กด๊ด๊ณ ์ฃผ์ ์ด ๋๋ฝ๋์๊ธฐ ๋๋ฌธ์ ๋ฐ์ํจ.
- ์์ฑ์ ์ฃผ์ ์ ์ฌ์ฉํ๋ฉด ์ฃผ์ ๋ฐ์ดํฐ ๋๋ฝ ์ ์ปดํ์ผ ์ค๋ฅ๊ฐ ๋ฐ์ํจ.
- final ํค์๋ ์ฌ์ฉ ๊ฐ๋ฅ
- ์์ฑ์ ์ฃผ์ ์ ์ฌ์ฉํ๋ฉด ํ๋์ final ํค์๋๋ฅผ ์ฌ์ฉํ ์ ์์.
- ์์ฑ์์์ ๊ฐ์ด ์ค์ ๋์ง ์์ผ๋ฉด ์ปดํ์ผ ์์ ์์ ์ค๋ฅ๋ฅผ ํ์ธ ํ ์ ์์.
- java: variable (๋ฐ์ดํฐ ์ด๋ฆ) might not have been initialized
- ์์ฑ์ ์ฃผ์ ์ ์ ์ธํ ๋๋จธ์ง ์ฃผ์ ๋ฐฉ์์ ์์ฑ์ ์ดํ์ ํธ์ถ๋๋ ํํ์ด๋ฏ๋ก final ํค์๋๋ฅผ ์ฌ์ฉ ๋ถ๊ฐ
- ์ํ ์ฐธ์กฐ
- ์ํ ์ฐธ์กฐ๋ฅผ ๋ฐฉ์งํ ์ ์์.
- ๊ฐ๋ฐํ๋ค๋ณด๋ฉด ์ฌ๋ฌ ์ปดํฌ๋ํธ ๊ฐ์ ์์กด์ฑ์ด ์๊ธฐ๊ฒ ๋จ (A→B๋ฅผ ์ฐธ์กฐํ๊ณ , B→ A๋ฅผ ์ฐธ์กฐ)
- ํ๋ ์ฃผ์
๊ณผ ์์ ์ ์ฃผ์
์ ๋น์ด ์์ฑ๋ ํ์ ์ฐธ์กฐ๋ฅผ ํ๊ธฐ ๋๋ฌธ์ ์ ํ๋ฆฌ์ผ์ด์
์ด ์ด๋ ํ ์ค๋ฅ์ ๊ฒฝ๊ณ ์์ด ๊ตฌ๋๋จ
- ์ค์ ์ฝ๋๊ฐ ํธ์ถ๋ ๋๊น์ง ๋ฌธ์ ๋ฅผ ์ ์ ์์.
- ์์ฑ์๋ฅผ ํตํด ์ฃผ์ ํ๊ฒ ๋๋ฉด BeanCurrentlyInCreationException์ด ๋ฐ์ํ๊ฒ ๋จ.
'Spring๐ธ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Spring Security - JWT ์ธ์ฆ(Authentication) (0) | 2023.05.17 |
---|---|
Spring MVC - JUnit์ ์ฌ์ฉํ ๋จ์ ํ ์คํธ (0) | 2023.04.30 |
Spring MVC - JDBC ๊ธฐ๋ฐ ๋ฐ์ดํฐ ์ก์ธ์ค ๊ณ์ธต (0) | 2023.04.18 |
Spring MVC - ์์ธ ์ฒ๋ฆฌ(1) (0) | 2023.04.17 |
Spring Framework ๊ธฐ๋ณธ, ํน์ง, ์ฌ์ฉํ๋ ์ด์ (0) | 2023.04.02 |