๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Back-end ๋ฐ๋ธŒ์ฝ”์Šค/week 03 - 05 TIL (Spring)

[TIL] 221102 - SpringBoot Part1 : Dependecy injection, ์ปดํฌ๋„ŒํŠธ ์Šค์บ”

by young-ji 2022. 11. 3.

SpringBoot Part1 (3)

 

Dependecy injection, Circular Dependency

 

IoC๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋‹ค์–‘ํ•œ ํŒจํ„ด๋“ค(์ „๋žต ํŒจํ„ด, ์„œ๋น„์Šค ๋กœ์ผ€์ดํ„ฐ ํŒจํ„ด, ํŒฉํ† ๋ฆฌ ํŒจํ„ด, ์˜์กด๊ด€๊ณ„ ์ฃผ์ž… ํŒจํ„ด) ์ค‘ ํ•˜๋‚˜์ด๋‹ค.

๊ฐ์ฒด๋ฅผ ์ฃผ์ž…๋ฐ›๋Š” ์ฑ„ํ„ด์„ ์ƒ์„ฑ์ž ์ฃผ์ž… ํŒจํ„ด์ด๋ผ๊ณ  ๋ถ€๋ฅด๋ฉฐ, ๊ทธ ์™ธ์—๋„ ์Šคํ”„๋ง์€ ์„ธํ„ฐ ๊ธฐ๋ฐ˜์˜ ์˜์กด ๊ด€๊ณ„๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

 

Dependency Resoulation Precess

์˜์กด๊ด€๊ณ„๊ฐ€ ํ˜•์„ฑ๋œ๋‹ค.

  1. ApplicationContext๋ฅผ ๋งŒ๋“ค์–ด์งˆ๋•Œ Configuration Metadata๋ฅผ ์ „๋‹ฌํ•˜๊ณ  ๊ทธ ์•ˆ์— Bean๋“ค์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ์žˆ๋‹ค. ( new AnnotationConfigApplicationContext(AppConfiguration.class) )
  2. ์ด๋•Œ ๊ฐ Bean์— ๋Œ€ํ•œ ์˜์กด๊ด€๊ณ„๊ฐ€ class ์†์„ฑ์ด๋‚˜ ์ƒ์„ฑ์ž, ์ธ์ž๋“ค์„ ํ†ตํ•ด ํ˜•์„ฑ๋œ๋‹ค.

 

Circular Dependecy

: ์˜์กด๊ด€๊ณ„๊ฐ€ ์ž˜๋ชป ํ˜•์„ฑ๋˜๋Š” ๊ฒฝ์šฐ !

: A→B ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  B→A๋ฅผ ์ฐธ์กฐํ• ๋•Œ, ์ˆœํ™˜ ์˜์กด๊ด€๊ณ„๊ฐ€ ํ˜•์„ฑ๋˜๋ฉฐ BeanCurrentlyInCreateionException ์˜ˆ์™ธ ๋ฐœ์ƒ

 


 

์ปดํฌ๋„ŒํŠธ ์Šค์บ”

 

: Spring์ด ์ง์ ‘ ํด๋ž˜์Šค๋ฅผ ๊ฒ€์ƒ‰ํ•ด์„œ Bean๋“ค์ด ์ž๋™์œผ๋กœ IoC ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋กํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ. ์„ค์ • ํด๋ž˜์Šค๋ฅผ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜์ง€ ์•Š์•„๋„ ์›ํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๋‹ค.

: Configuration class์— Bean์„ ์ง์ ‘ class๋ฅผ ์ƒ์„ฑ, ์ •์˜ํ•ด์ฃผ์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

 

 

์Šคํ”„๋ง์€ ์–ด๋–ค ์‹์œผ๋กœ ์ž๋™์œผ๋กœ ๋“ฑ๋ก๋  Bean์„ ์ธ์‹ํ• ๊นŒ?

⇒ ์ŠคํŠธ๋ ˆ์˜ค ํƒ€์ž…

: Stereotype ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•˜๋ฉด ์Šค์บ”๋Œ€์ƒ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

: ๊ณ ์ •๊ด€๋…์ด๋ผ๋Š” ๋œป์˜ ์šฉ์–ด๋กœ UML์—์„œ ์˜จ ๊ฐœ๋…

→ UML ๋‹ค์ด์–ด๊ทธ๋žจ์„ ํ™•์žฅ์‹œ์ผœ์ฅฌ๋Š” ๋„๊ตฌ๋กœ ์ƒํ™ฉ์ด๋‚˜ ๋„๋ฉ”์ธ์— ๋งž๊ฒŒ ๋ถ„๋ฅ˜๋ฅผ ํ•ด์ค€๋‹ค.

UML ๋‹ค์ด์–ด๊ทธ๋žจ
component ์ƒ์†

์ถœ์ฒ˜ - https://incheol-jung.gitbook.io/docs/q-and-a/spring/stereo-type

 

Spring 2.5๋ถ€ํ„ฐ ๋ฒ”์šฉ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์˜€์œผ๋ฉฐ ์ด์ „๊นŒ์ง€๋Š” xml ํŒŒ์ผ์— bean์„ ๋“ฑ๋กํ•˜์—ฌ ๊ด€๋ฆฌํ•˜์˜€๋Š”๋‹ค.

Stereo type์„ ํ†ตํ•ด ๊ฐ๊ฐ์˜ ์šฉ๋„์— ๋งž๊ฒŒ Bean์„ ๋ถ„๋ฅ˜ํ•ด์ค€๋‹ค.

 

  • @Component

@Configuration : ํ•ด๋‹น class๊ฐ€ java ๊ธฐ๋ฐ˜์œผ๋กœ meta ๋ฐ์ดํ„ฐ๋ฅผ ์„ค์ •ํ•˜๋Š” class์ด๋‹ค.

@Controller : MVC controller๋กœ ์ธ์‹

@Service : ๋น„์ง€๋‹ˆ์Šค ์„œ๋น„์Šค ๊ณ„์ธต์œผ๋กœ ์ธ์‹

@Repository : ์Šคํ”„๋ง ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๊ณ„์ธต์œผ๋กœ ์ธ์‹ํ•˜๊ณ  ํ•ด๋‹น ๊ณ„์ธต์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์˜ˆ์™ธ๋Š” ๋ชจ๋‘ DataAccessException์œผ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

 

  • @ComponetScan

: ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์ž๋™์œผ๋กœ ๋“ฑ๋ก๋˜๊ฒŒ ์•Œ๋ ค์ค€๋‹ค. → ํ•ด๋‹น class๊ฐ€ ์žˆ๋Š” ํŒจํ‚ค์ง€ ๊ธฐ์ค€์œผ๋กœ Beand์„ ์ฐพ์Œ.

: (basePackages = {”org.progrms.kdt.order”,”org.progrms.kdt.voucher”}) ํ˜น์€

(basePackageClasses = {Order.class,Voucher.class}) ์ธ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์Šค์บ”ํ•  ํŒจํ‚ค์ง€๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

: excludeFilters๋ฅผ ํ†ตํ•ด ์ œ์™ธ๋„ ๊ฐ€๋Šฅ

 


 

Autowired

 

์˜์กด๊ด€๊ณ„ ์ž๋™ ์ฃผ์ž….

์ƒ์„ฑ์ž๋ฅผ ์ƒ๋žตํ•˜๊ณ  field ํ˜น์€ set๋ฉ”์†Œ๋“œ์— @Autowired ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ถ™์—ฌ ์ž๋™ ์ฃผ์ž…์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

๋ณ€๊ฒฝ์ „

@Service
public class VoucherService {
    private final VoucherRepository voucherRepository;

    public VoucherService(VoucherRepository voucherRepository) {
        this.voucherRepository = voucherRepository;
    }

    public Voucher getVoucher(UUID voucherId) {
        return  voucherRepository.findById(voucherId)
                .orElseThrow(() -> new RuntimeException("Can not find a voucher for " + voucherId));
    }

    public void useVoucher(Voucher voucher) {
    }
}

 

๋ณ€๊ฒฝํ›„

@Service
public class VoucherService {

    @Autowired
    private VoucherRepository voucherRepository;

    public Voucher getVoucher(UUID voucherId) {
        return  voucherRepository.findById(voucherId)
                .orElseThrow(() -> new RuntimeException("Can not find a voucher for " + voucherId));
    }

    public void useVoucher(Voucher voucher) {
    }
}

 

  • ์ƒ์„ฑ์ž๊ฐ€ 2๊ฐœ์ผ ๊ฒฝ์šฐ, ์ž๋™์ฃผ์ž…์ด ๋˜์–ด์•ผํ•˜๋Š” ๋ฉ”์†Œ๋“œ์— @Autowired๋ฅผ ๋‹ฌ์•„์ค˜์•ผํ•œ๋‹ค.
@Service
public class VoucherService {
    private VoucherRepository voucherRepository;

		public VoucherService() {}

		@Autowired
    public VoucherService(VoucherRepository voucherRepository) {
        this.voucherRepository = voucherRepository;
    }

    public Voucher getVoucher(UUID voucherId) {
        return  voucherRepository.findById(voucherId)
                .orElseThrow(() -> new RuntimeException("Can not find a voucher for " + voucherId));
    }

    public void useVoucher(Voucher voucher) {
    }
}

 

์ƒ์„ฑ์ž ๊ธฐ๋ฐ˜ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…์„ ์„ ํƒํ•ด์•ผํ•˜๋Š” ์ด์œ 

  • ์ดˆ๊ธฐํ™”์‹œ ํ•„์š”ํ•œ ๋ชจ๋“  ์˜์กด๊ด€๊ณ„๊ฐ€ ํ˜•์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์•ˆ์ „ํ•˜๋‹ค. (๋งŒ์•ฝ field๋ฅผ ๋‚˜์ค‘์— setํ•ด์•ผํ•ด์„œ ์—†์„๊ฒฝ์šฐ Optional ํƒ€์ž…์œผ๋กœ ์ •์˜)
  • ์ž˜๋ชป๋œ ํŒจํ„ด์„ ์ฐพ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ค€๋‹ค.
  • ํ…Œ์ŠคํŠธ๋ฅผ ์‰ฝ๊ฒŒ ํ•ด์ค€๋‹ค.
  • ๋ถˆ๋ณ€์„ฑ์„ ํ™•๋ณดํ•œ๋‹ค. final ํ‚ค์›Œ๋“œ →thread safe ํ™•๋ณด

 

๋˜‘๊ฐ™์€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฐ์ฒด๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ์ผ๋•Œ

์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ฃผ์ž… ๋ฐ›๋Š”๋ฐ ์—ฌ๋Ÿฌ๊ฐœ์˜ bean์ด ๊ตฌํ˜„๋˜์–ด์žˆ์„๋•Œ ์–ด๋–ค bean์ด ์ฃผ์ž…์ด ๋˜์–ด์•ผํ•˜๋Š”์ง€ ์•Œ๋ ค์ค˜์•ผํ•œ๋‹ค.

  1. @Primary ๋“ฑ๋กํ•ด์„œ ์šฐ์„ ์ˆœ์œ„ ์ฃผ๊ธฐ
  2. @Qualifier(”์ด๋ฆ„”) ์„ ํ†ตํ•ด ๊ตฌ๋ถ„ํ•˜๊ธฐ

 

Bean์ด ์—ฌ๋Ÿฌ๊ฐœ์ผ๋•Œ Configuration์„ ์—ฌ๋Ÿฌ๊ฐœ ์ƒ์„ฑํ•˜์—ฌ Bean ์„ค์ •์„ ๋ถ„๋ฅ˜์— ๋งž๊ฒŒ ์ž˜ ๊ตฌ๋ถ„ํ•ด ์ค˜์•ผํ•œ๋‹ค.

: @Configuration ์• ๋…ธํ…Œ์ด์…˜ ๋˜ํ•œ ์ปดํฌ๋„ŒํŠธ ์Šค์บ”์˜ ๋Œ€์ƒ์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์„ค์ •์„ ์—ฌ๋Ÿฌ ํŒŒ์ผ๋กœ ๋ถ„ ๋ฆฌํ•˜๊ณ  ๋ฉ”์ธ์ด ๋˜๋Š” ๊ณณ์—์„œ ์ปดํฌ๋„ŒํŠธ ์Šค์บ”์œผ๋กœ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜๋„์žˆ๋‹ค. ์‹ค์ œ๋กœ ๋ณต์žกํ•œ ์ƒ์šฉ ์Šคํ”„๋ง ์–ด ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค๋‹ค๋ณด๋ฉด ์„ค์ •ํ•  ๋‚ด์šฉ์ด ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๋Ÿฌ ํŒŒ์ผ๋กœ ๋‚˜๋ˆ„๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

: SpringBoot๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด @SpringBootApplication์„ ์ด์šฉํ•˜๋Š”๋ฐ ์‹ค์ œ ์ด๊ณณ์—์„œ ์ปดํฌ๋„ŒํŠธ ์Šค์บ”์ด ์ผ์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ํด๋ž˜์Šค ๊ธฐ์ค€์œผ๋กœ ์Šค์บ”์ด ์ผ์–ด๋‚˜๊ณ , ๋ณ„๋„์˜ ๋ฃจํŠธ @Configuration ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ์ค„ ํ•„์š”๊ฐ€ ์—†๋‹ค.

 


 

Beans Scope

 

๊ณต์‹๋ฌธ์„œ๋ฅผ ๋ณด๋ฉด ์ด 6๊ฐœ์˜ ์Šค์ฝฅ์„ ๋ณผ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ธฐ๋ณธ์ ์œผ๋กœ ์‹ฑ๊ธ€ํ†ค ์Šค์ฝฅ์„ ๊ฐ€์ง„๋‹ค.(default)

 

์‹ฑ๊ธ€ํ†ค ์Šค์ฝฅ

ApplicationContext์—์„œ getBean์„ ํ• ๋•Œ ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๊ฐ์ฒด๊ฐ€ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๋œ๋‹ค.

var voucherRepository = applicationContext.getBean(VoucherRepository.class);
var voucherRepository2 = applicationContext.getBean(VoucherRepository.class);

System.out.println(voucherRepository == voucherRepository2); // True

 

 

ํ”„๋กœํ† ํƒ€์ž… ์Šค์ฝฅ

๋งค๋ฒˆ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ์„๋•Œ ํ”„๋กœํ† ํƒ€์ž… ์Šค์ฝฅ์„ ์ •์˜ํ•ด ์ค€๋‹ค.

@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)

@Repository
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class MemoryVoucherRepository implements VoucherRepository {

    .....
}
var voucherRepository = applicationContext.getBean(VoucherRepository.class);
var voucherRepository2 = applicationContext.getBean(VoucherRepository.class);

System.out.println(voucherRepository == voucherRepository2); // False

 


 

Bean Lifescycle Callbacks

 

Spring Application Context๋Š” ๊ฐ์ฒด ์ƒ์„ฑ๊ณผ ์†Œ๋ฉธ์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌ

 

Bean ์ƒ์„ฑ ์ƒ๋ช…์ฃผ๊ธฐ ์ฝœ๋ฐฑ

  1. @PostConstruct ์• ๋…ธํ…Œ์ด์…˜์ด ์ ์šฉ๋œ ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ
  2. Bean์ด InitializingBean ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„์‹œ afterPropertiesSet ํ˜ธ์ถœ
  3. @Bean ์• ๋…ธํ…Œ์ด์…˜์˜ initMethod ์— ์„ค์ •ํ•œ ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ

: ์ƒ์„ฑ๋ ๋•Œ ์ˆ˜ํ–‰๋˜์•ผํ•˜๋Š” ๋™์ž‘์ด ์žˆ์„ ๊ฒฝ์šฐ ๊ตฌํ˜„

 

Bean ์†Œ๋ฉธ ์ƒ๋ช…์ฃผ๊ธฐ ์ฝœ๋ฐฑ

  1. @PreDestory ์• ๋…ธํ…Œ์ด์…˜์ด ์ ์šฉ๋œ ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ
  2. Bean์ด DisposableBean ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„์‹œ destroy ํ˜ธ์ถœ
  3. @Bean ์• ๋…ธํ…Œ์ด์…˜์˜ destroyMethod ์— ์„ค์ •ํ•œ ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ

 

→ clean up , ๋„คํŠธ์›Œํฌ close๊ฐ™์€ ์ž‘์—…์ด ์žˆ์„๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

 

 

 

 


Daliy Mission

  • ์ปดํฌ๋„ŒํŠธ ์Šค์บ”์„ ํ†ตํ•ด ๋นˆ์ด ๋“ฑ๋ก๋˜๊ฒŒ ๊ตฌํ˜„ํ•ด๋ณด๊ธฐ
  • ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๊ฐ€ ์•„๋‹Œ ํŒŒ์ผ๋กœ ๊ด€๋ฆฌ๊ฐ€ ๋˜๋Š” Repository ๋งŒ๋“ค์–ด๋ณด๊ธฐ
    • ๊ธฐ์กด ๋ฉ”๋ชจ๋ฆฌ ๋ ˆํฌ์ง€ํ† ๋ฆฌ ๋ณ„๋„๋กœ ๋ณด๊ด€

 

 

์ถœ์ฒ˜ - ํ•ด๋ฆฌ : SpringBoot Part1

 

๋Œ“๊ธ€