Home > SpringBoot > ๐Ÿ›๏ธ[SpringBoot] ์Šคํ”„๋ง ๋ถ€ํŠธ์˜ ํ•ต์‹ฌ ๊ฐœ๋…`:` ์ œ์–ด์˜ ์—ญ์ „(IoC) - XML ๊ธฐ๋ฐ˜ ๊ตฌํ˜„

๐Ÿ›๏ธ[SpringBoot] ์Šคํ”„๋ง ๋ถ€ํŠธ์˜ ํ•ต์‹ฌ ๊ฐœ๋…`:` ์ œ์–ด์˜ ์—ญ์ „(IoC) - XML ๊ธฐ๋ฐ˜ ๊ตฌํ˜„
SpringBoot

๐Ÿ›๏ธ[SpringBoot] ์Šคํ”„๋ง ๋ถ€ํŠธ์˜ ํ•ต์‹ฌ ๊ฐœ๋…: ์ œ์–ด์˜ ์—ญ์ „(IoC) - XML ๊ธฐ๋ฐ˜ ๊ตฌํ˜„

๐Ÿ“– ๊ฐœ์š”

์ œ์–ด์˜ ์—ญ์ „(IoC, Inversion of Control) ์€ ๊ฐ์ฒด์˜ ์ƒ์„ฑ๊ณผ ์˜์กด์„ฑ ๊ด€๋ฆฌ๋ฅผ ๊ฐœ๋ฐœ์ž๊ฐ€ ์•„๋‹Œ Spring Container ๊ฐ€ ๋‹ด๋‹นํ•˜๋„๋ก ํ•˜๋Š” ์„ค๊ณ„ ์›์น™์ž…๋‹ˆ๋‹ค. XML ์„ค์ • ํŒŒ์ผ์„ ํ†ตํ•ด IoC๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์ „ํ†ต์ ์ธ ๋ฐฉ๋ฒ•์„ ํ•™์Šตํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


๐Ÿšจ ๊ธฐ์กด ์˜์กด์„ฑ ์ฃผ์ž…์˜ ํ•œ๊ณ„์ 

์—ฌ์ „ํžˆ ๋‚จ์€ ๋ฌธ์ œ์ 

์ด์ „์— ์˜์กด์„ฑ ์ฃผ์ž…์„ ํ†ตํ•ด ํด๋ž˜์Šค ๊ฐ„ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ท„์ง€๋งŒ, ์—ฌ์ „ํžˆ ์ˆ˜์ •์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„์ด ์žˆ์Šต๋‹ˆ๋‹ค:

public class Main {
    public static void main(String[] args) {
        CoffeeMaker coffeeMaker = new CoffeeMaker();
        
        // ๐Ÿšจ ์ƒˆ๋กœ์šด ์ปคํ”ผ ๋จธ์‹ ์ด ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค ์ด ๋ถ€๋ถ„์„ ์ˆ˜์ •ํ•ด์•ผ ํ•จ
        coffeeMaker.setCoffeeMachine(new DripCoffeeMachine());
        coffeeMaker.makeCoffee();
        
        // ๋‹ค๋ฅธ ์ปคํ”ผ ๋จธ์‹ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ๋˜ ์ˆ˜์ • ํ•„์š”
        coffeeMaker.setCoffeeMachine(new EspressoMachine());
        coffeeMaker.makeCoffee();
    }
}

๋ณต์žกํ•œ ์˜์กด์„ฑ ๊ด€๊ณ„์—์„œ์˜ ๋ฌธ์ œ์ 

// ์‹ค์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ์ด๋Ÿฐ ๋ณต์žกํ•œ ์˜์กด์„ฑ ๊ด€๊ณ„๊ฐ€ ๋ฐœ์ƒ
UserService userService = new UserService();
PaymentService paymentService = new PaymentService();
EmailService emailService = new EmailService();
OrderService orderService = new OrderService();

// ์˜์กด์„ฑ ์ฃผ์ž…
userService.setUserRepository(new UserRepository());
paymentService.setPaymentGateway(new StripePaymentGateway());
emailService.setEmailProvider(new GmailProvider());
orderService.setUserService(userService);
orderService.setPaymentService(paymentService);
orderService.setEmailService(emailService);

// ๐Ÿšจ ๋งค๋ฒˆ ์ด๋Ÿฐ ๋ณต์žกํ•œ ์„ค์ • ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•จ

๐Ÿ”„ ์ œ์–ด์˜ ์—ญ์ „(IoC) ๊ฐœ๋…

์ „ํ†ต์  ๋ฐฉ์‹ vs IoC ๋ฐฉ์‹

๊ตฌ๋ถ„ ์ „ํ†ต์  ๋ฐฉ์‹ IoC ๋ฐฉ์‹
๊ฐ์ฒด ์ƒ์„ฑ ๊ฐœ๋ฐœ์ž๊ฐ€ new ํ‚ค์›Œ๋“œ๋กœ ์ง์ ‘ ์ƒ์„ฑ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ž๋™ ์ƒ์„ฑ
์˜์กด์„ฑ ์ฃผ์ž… ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ๋กœ ์ง์ ‘ ์ฃผ์ž… ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ž๋™ ์ฃผ์ž…
ํ๋ฆ„ ์ œ์–ด ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ์ œ์–ด ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๊ฐ„์ ‘ ์ œ์–ด
์„ค์ • ๋ฐฉ๋ฒ• ์†Œ์Šค์ฝ”๋“œ ๋‚ด๋ถ€์—์„œ ํ•˜๋“œ์ฝ”๋”ฉ ์™ธ๋ถ€ ์„ค์ • ํŒŒ์ผ ๋˜๋Š” ์• ๋…ธํ…Œ์ด์…˜

IoC์˜ ํ•ต์‹ฌ ์•„์ด๋””์–ด

graph TB
    A[๊ฐœ๋ฐœ์ž] -->|์ œ์–ด๊ถŒ ์ด์–‘| B[Spring Container]
    B -->|๊ฐ์ฒด ์ƒ์„ฑ| C[Bean Objects]
    B -->|์˜์กด์„ฑ ์ฃผ์ž…| D[Dependency Injection]
    B -->|์ƒ๋ช…์ฃผ๊ธฐ ๊ด€๋ฆฌ| E[Lifecycle Management]

๐Ÿ“„ XML ๊ธฐ๋ฐ˜ IoC ๊ตฌํ˜„

1๋‹จ๊ณ„: XML ์Šคํ‚ค๋งˆ ์ค€๋น„

Spring Framework์˜ ๊ณต์‹ XML ์Šคํ‚ค๋งˆ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค:

2๋‹จ๊ณ„: beans.xml ํŒŒ์ผ ์ƒ์„ฑ

ํŒŒ์ผ ์œ„์น˜: src/main/resources/beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- ๋“œ๋ฆฝ ์ปคํ”ผ ๋จธ์‹  Bean ์ •์˜ -->
    <bean id="dripCoffeeMachine" class="com.example.demo.DripCoffeeMachine"/>
    
    <!-- ์—์Šคํ”„๋ ˆ์†Œ ๋จธ์‹  Bean ์ •์˜ -->
    <bean id="espressoMachine" class="com.example.demo.EspressoMachine"/>
    
    <!-- ์ปคํ”ผ ๋ฉ”์ด์ปค Bean ์ •์˜ ๋ฐ ์˜์กด์„ฑ ์ฃผ์ž… -->
    <bean id="coffeeMaker" class="com.example.demo.CoffeeMaker" init-method="makeCoffee">
        <property name="coffeeMachine" ref="espressoMachine"/>
    </bean>
    
</beans>

3๋‹จ๊ณ„: ํด๋ž˜์Šค ๊ตฌ์กฐ ์ •์˜

์ธํ„ฐํŽ˜์ด์Šค

public interface CoffeeMachine {
    String brew();
}

๊ตฌํ˜„์ฒด๋“ค

public class EspressoMachine implements CoffeeMachine {
    @Override
    public String brew() {
        return "Brewing coffee with Espresso Machine";
    }
}

public class DripCoffeeMachine implements CoffeeMachine {
    @Override
    public String brew() {
        return "Brewing coffee with Drip Coffee Machine";
    }
}

CoffeeMaker ํด๋ž˜์Šค

public class CoffeeMaker {
    private CoffeeMachine coffeeMachine;
    
    // Setter ๋ฉ”์„œ๋“œ (XML์—์„œ property ์ฃผ์ž…์„ ์œ„ํ•ด ํ•„์š”)
    public void setCoffeeMachine(CoffeeMachine coffeeMachine) {
        this.coffeeMachine = coffeeMachine;
    }
    
    // init-method๋กœ ์ง€์ •๋  ๋ฉ”์„œ๋“œ
    public void makeCoffee() {
        System.out.println(coffeeMachine.brew());
    }
}

4๋‹จ๊ณ„: Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ค์ •

@SpringBootApplication
@ImportResource("classpath:beans.xml")  // XML ์„ค์ • ํŒŒ์ผ import
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

๐Ÿงฉ XML ์„ค์ • ํŒŒ์ผ ๊ตฌ์„ฑ ์š”์†Œ

<bean> ํƒœ๊ทธ ์†์„ฑ๋“ค

์†์„ฑ ์„ค๋ช… ์˜ˆ์‹œ
id Bean์˜ ๊ณ ์œ  ์‹๋ณ„์ž id="coffeeMaker"
class Bean์œผ๋กœ ์ƒ์„ฑํ•  ํด๋ž˜์Šค (์ „์ฒด ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ) class="com.example.demo.CoffeeMaker"
init-method ๊ฐ์ฒด ์ƒ์„ฑ ํ›„ ์ž๋™ ์‹คํ–‰ํ•  ๋ฉ”์„œ๋“œ init-method="makeCoffee"
destroy-method ๊ฐ์ฒด ์†Œ๋ฉธ ์ „ ์‹คํ–‰ํ•  ๋ฉ”์„œ๋“œ destroy-method="cleanup"

<property> ํƒœ๊ทธ - ์˜์กด์„ฑ ์ฃผ์ž…

<!-- Setter ์ฃผ์ž… -->
<bean id="coffeeMaker" class="com.example.demo.CoffeeMaker">
    <property name="coffeeMachine" ref="espressoMachine"/>
    <property name="maxCapacity" value="500"/>
</bean>

<!-- ์ƒ์„ฑ์ž ์ฃผ์ž… -->
<bean id="coffeeMaker" class="com.example.demo.CoffeeMaker">
    <constructor-arg ref="espressoMachine"/>
    <constructor-arg value="500"/>
</bean>

๐Ÿš€ ์‹คํ–‰ ํ๋ฆ„ ๋ถ„์„

1. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘

SpringApplication.run(DemoApplication.class, args);

2. XML ํŒŒ์ผ ๋กœ๋”ฉ

@ImportResource("classpath:beans.xml")

3. Spring Container์˜ ์ž‘์—… ์ˆœ์„œ

  1. Bean ์ •์˜ ํŒŒ์‹ฑ: XML์—์„œ Bean ์ •๋ณด๋ฅผ ์ฝ์–ด๋“ค์ž„
  2. ๊ฐ์ฒด ์ƒ์„ฑ: ๊ฐ Bean ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
    DripCoffeeMachine dripCoffeeMachine = new DripCoffeeMachine();
    EspressoMachine espressoMachine = new EspressoMachine();
    CoffeeMaker coffeeMaker = new CoffeeMaker();
    
  3. ์˜์กด์„ฑ ์ฃผ์ž…: <property> ํƒœ๊ทธ์— ๋”ฐ๋ผ ์˜์กด์„ฑ ์ฃผ์ž…
    coffeeMaker.setCoffeeMachine(espressoMachine);
    
  4. ์ดˆ๊ธฐํ™” ๋ฉ”์„œ๋“œ ์‹คํ–‰: init-method ์‹คํ–‰
    coffeeMaker.makeCoffee(); // ์ž๋™ ์‹คํ–‰
    

4. ์‹คํ–‰ ๊ฒฐ๊ณผ

Brewing coffee with Espresso Machine

โœ… XML ๊ธฐ๋ฐ˜ IoC์˜ ์žฅ์ 

๐ŸŽฏ ์ฝ”๋“œ ๋ณ€๊ฒฝ ์—†๋Š” ์„ค์ • ๋ณ€๊ฒฝ

<!-- ์—์Šคํ”„๋ ˆ์†Œ ๋จธ์‹ ์—์„œ ๋“œ๋ฆฝ ๋จธ์‹ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด XML๋งŒ ์ˆ˜์ • -->
<bean id="coffeeMaker" class="com.example.demo.CoffeeMaker" init-method="makeCoffee">
    <property name="coffeeMachine" ref="dripCoffeeMachine"/>  <!-- ์—ฌ๊ธฐ๋งŒ ๋ณ€๊ฒฝ! -->
</bean>

๐Ÿ—๏ธ ์ค‘์•™์ง‘์ค‘์‹ ์„ค์ • ๊ด€๋ฆฌ

  • ๋ชจ๋“  Bean ์„ค์ •์„ ํ•œ ๊ณณ์—์„œ ๊ด€๋ฆฌ
  • ์˜์กด์„ฑ ๊ด€๊ณ„๋ฅผ ํ•œ๋ˆˆ์— ํŒŒ์•… ๊ฐ€๋Šฅ
  • ํ™˜๊ฒฝ๋ณ„ ์„ค์ • ๋ถ„๋ฆฌ ์šฉ์ด

๐Ÿ”ง ์œ ์—ฐํ•œ ๊ฐ์ฒด ์ƒ๋ช…์ฃผ๊ธฐ ์ œ์–ด

<bean id="databaseConnection" 
      class="com.example.DatabaseConnection"
      init-method="connect"
      destroy-method="disconnect"
      scope="singleton">
    <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
</bean>

โš ๏ธ XML ๊ธฐ๋ฐ˜ IoC์˜ ํ•œ๊ณ„์ 

1. ์ปดํŒŒ์ผ ํƒ€์ž„ ๊ฒ€์ฆ ๋ถˆ๊ฐ€

<!-- ์˜คํƒ€๊ฐ€ ์žˆ์–ด๋„ ์‹คํ–‰ ์‹œ์ ์—๋งŒ ์—๋Ÿฌ ๋ฐœ์ƒ -->
<bean id="coffeeMaker" class="com.example.demo.CoffeeMakr">  <!-- ์˜คํƒ€! -->
    <property name="coffeeMachin" ref="espressoMachine"/>    <!-- ์˜คํƒ€! -->
</bean>

2. IDE ์ง€์› ์ œํ•œ

  • ์ž๋™์™„์„ฑ, ๋ฆฌํŒฉํ† ๋ง ์ง€์› ๋ถ€์กฑ
  • ํด๋ž˜์Šค๋ช… ๋ณ€๊ฒฝ ์‹œ XML ํŒŒ์ผ ์ˆ˜๋™ ์ˆ˜์ • ํ•„์š”

3. XML ํŒŒ์ผ ๋ณต์žก์„ฑ ์ฆ๊ฐ€

๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” XML ํŒŒ์ผ์ด ๋งค์šฐ ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ†š ํ˜„๋Œ€์  ์ ‘๊ทผ๋ฒ•๊ณผ์˜ ๋น„๊ต

Annotation ๊ธฐ๋ฐ˜ ์„ค์ • (ํ˜„์žฌ ๊ถŒ์žฅ ๋ฐฉ์‹)

@Component
public class EspressoMachine implements CoffeeMachine {
    // ๊ตฌํ˜„
}

@Component
public class CoffeeMaker {
    private final CoffeeMachine coffeeMachine;
    
    @Autowired
    public CoffeeMaker(CoffeeMachine coffeeMachine) {
        this.coffeeMachine = coffeeMachine;
    }
    
    @PostConstruct
    public void makeCoffee() {
        System.out.println(coffeeMachine.brew());
    }
}

Java Config ๊ธฐ๋ฐ˜ ์„ค์ •

@Configuration
public class CoffeeConfig {
    
    @Bean
    public CoffeeMachine espressoMachine() {
        return new EspressoMachine();
    }
    
    @Bean
    public CoffeeMaker coffeeMaker(CoffeeMachine coffeeMachine) {
        CoffeeMaker maker = new CoffeeMaker();
        maker.setCoffeeMachine(coffeeMachine);
        return maker;
    }
}

๐ŸŽฏ ์–ธ์ œ XML ์„ค์ •์„ ์‚ฌ์šฉํ• ๊นŒ?

์ ํ•ฉํ•œ ๊ฒฝ์šฐ

  • ๋ ˆ๊ฑฐ์‹œ ์‹œ์Šคํ…œ ํ†ตํ•ฉ: ๊ธฐ์กด XML ๊ธฐ๋ฐ˜ ์„ค์ •๊ณผ์˜ ํ˜ธํ™˜์„ฑ ํ•„์š”
  • ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์ •: ์†Œ์Šค ์ฝ”๋“œ ์ˆ˜์ •์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ์„œ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • ๋Ÿฐํƒ€์ž„ ์„ค์ • ๋ณ€๊ฒฝ: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์žฌ๋ฐฐํฌ ์—†์ด ์„ค์ • ๋ณ€๊ฒฝ ํ•„์š”

ํ˜„์žฌ ๊ถŒ์žฅ ๋ฐฉ์‹

  • Annotation ๊ธฐ๋ฐ˜: @Component, @Service, @Repository
  • Java Config: @Configuration, @Bean
  • Spring Boot Auto Configuration: @SpringBootApplication

๐Ÿ’ก ์‹ค๋ฌด ํŒ

XML๊ณผ Annotation ํ˜ผ์šฉ

@SpringBootApplication
@ImportResource("classpath:legacy-beans.xml")  // ๋ ˆ๊ฑฐ์‹œ XML ์„ค์ •
public class ModernApplication {
    // ํ˜„๋Œ€์  ์• ๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜ ์ฝ”๋“œ
}

Profile๋ณ„ XML ์„ค์ •

<!-- beans-dev.xml -->
<beans profile="dev">
    <bean id="dataSource" class="com.example.DevDataSource"/>
</beans>

<!-- beans-prod.xml -->
<beans profile="prod">  
    <bean id="dataSource" class="com.example.ProdDataSource"/>
</beans>

๐ŸŽ“ ํ•™์Šต ํฌ์ธํŠธ

ํ•ต์‹ฌ ๊ฐœ๋…

  1. ์ œ์–ด์˜ ์—ญ์ „: ๊ฐ์ฒด ์ƒ์„ฑ๊ณผ ๊ด€๋ฆฌ ์ฑ…์ž„์„ ํ”„๋ ˆ์ž„์›Œํฌ์— ์œ„์ž„
  2. ์™ธ๋ถ€ ์„ค์ •: ์ฝ”๋“œ ๋ณ€๊ฒฝ ์—†์ด ์„ค์ • ํŒŒ์ผ๋งŒ์œผ๋กœ ๋™์ž‘ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ
  3. ์ƒ๋ช…์ฃผ๊ธฐ ๊ด€๋ฆฌ: init-method, destroy-method๋ฅผ ํ†ตํ•œ ๊ฐ์ฒด ์ƒ๋ช…์ฃผ๊ธฐ ์ œ์–ด

๋‹ค์Œ ํ•™์Šต ๋‹จ๊ณ„

  • Annotation ๊ธฐ๋ฐ˜ IoC: @Component, @Autowired ๋“ฑ
  • Java Config: @Configuration, @Bean
  • Spring Boot Auto Configuration: ์ž๋™ ์„ค์ •์˜ ์›๋ฆฌ
  • Bean Scope: Singleton, Prototype, Request, Session

XML ๊ธฐ๋ฐ˜ IoC๋Š” Spring Framework์˜ ๊ธฐ์ดˆ๋ฅผ ์ดํ•ดํ•˜๋Š” ๋ฐ ์ค‘์š”ํ•œ ๊ฐœ๋…์ด์ง€๋งŒ, ํ˜„์žฌ๋Š” ๋” ๊ฐ„ํŽธํ•˜๊ณ  ํƒ€์ž… ์•ˆ์ „ํ•œ Annotation ๊ธฐ๋ฐ˜ ์„ค์ •์„ ์ฃผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.