Spring Bean & μ£Όμž…(Injection)

3 λΆ„ μ†Œμš”

Bean & Injection

  • Bean

    Spring Framework μ—μ„œ Bean μ΄λž€ Spring IoC μ»¨ν…Œμ΄λ„ˆκ°€ κ΄€λ¦¬ν•˜λŠ” μžλ°” 객체λ₯Ό λœ»ν•œλ‹€. κ°„λ‹¨ν•˜κ²Œ μ„€λͺ…ν•˜μžλ©΄, μžλ°”μ˜ new μ—°μ‚°μžλ₯Ό 톡해 μƒμ„±ν•˜λŠ” κ°μ²΄λŠ” Bean 이라고 말할 수 μ—†λ‹€. κ°„ν˜Ή Spring 기반의 ν”„λ‘œμ νŠΈμ—μ„œ λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ„ λ‹΄κ³ μžˆλŠ” λ©”μ„œλ“œλ₯Ό 가진 ν΄λž˜μŠ€μ— μ•„λž˜μ™€ 같은 μ½”λ“œλ₯Ό λ³Ό 수 μžˆμ„ 것이닀.

    @Autowired
    private TestBean testBean;
      
    public void λ©”μ„œλ“œ() {
      
     this.testBean.doSomething();
    }
    

    testBean μ΄λΌλŠ” TestBean의 객체 λ³€μˆ˜λŠ” Spring IoC μ»¨ν…Œμ΄λ„ˆλ₯Ό 톡해 객체λ₯Ό μ£Όμž… λ°›μ•„ μ‚¬μš©λ˜λŠ” 것이닀.

    κ·Έλ ‡λ‹€λ©΄ β€˜μ–΄λ–»κ²Œβ€™ Spring IoC μ»¨ν…Œμ΄λ„ˆμ— Bean을 λ“±λ‘ν•˜λŠ”μ§€ λŒ€ν‘œμ μΈ 방법은 λ‹€μŒκ³Ό κ°™λ‹€.

    1. Java Annotation

      Annotation으둜 Bean을 등둝 ν•  λ•Œμ—λŠ”, λ“±λ‘ν•˜λ €λŠ” ν΄λž˜μŠ€μ— @Component, @Controller, @Service, @Repository μ–΄λ…Έν…Œμ΄μ…˜μ΄ ν•„μ—°μ μœΌλ‘œ λͺ…μ‹œλ˜μ–΄μ•Ό ν•œλ‹€. ν•΄λ‹Ή Annotation을 κΈ°μž¬ν•˜λ©΄μ„œ, Spring IoC μ»¨ν…Œμ΄λ„ˆμ— 이 클래슀λ₯Ό 빈으둜 λ“±λ‘ν•˜κ² λ‹€ 라고 λͺ…μ‹œν•˜λŠ”κ²ƒμ΄λ‹€.

      @Component
      public class TestBean {
           		
          private String name;
          ...
      }
           
      @Controller
      public class TestController {
          ...
      }
           
      @Service
      public class TestService {
          ...
      }
      

      Spring 기초 상식

      @Component, @Controller, @Service, @Repository λŠ” λ‹€ λ˜‘κ°™λ‹€?

      λ°˜μ€ 맞고 λ°˜μ€ 틀리닀. κΈ°λŠ₯μ μœΌλ‘œλŠ” λͺ¨λ“  Bean 객체에 μ–΄λ–€ μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜λ˜, 사싀상 μ „λΆ€ @Componentλ₯Ό μ‚¬μš©ν•΄λ„ λ‘œμ§μ„ κ΅¬μ„±ν•˜λŠ”λ°μ— 별 λ¬Έμ œλŠ” μ—†λ‹€.

      ν•˜μ§€λ§Œ Spring Framework μžμ²΄λŠ” ν˜‘μ—…κ³Ό 생산성 ν–₯상을 μœ„ν•΄μ„œ λ§Œλ“€μ–΄μ§„ ν”„λ ˆμž„μ›Œν¬μ΄λ©°(이 외에도 μ•ˆμ •μ„±, λ³΄μ•ˆμ„± λ“±λ“± λ§Žμ€ 것이 μžˆλ‹€.),

      개발 ν”„λ‘œμ νŠΈμ—μ„œλŠ” λ™μ—…μžλ“€λΌλ¦¬ β€˜μ–Έμ–΄β€™κ°€ μ•„λ‹Œ β€˜μ½”λ“œβ€™λ‘œ μ†Œν†΅ν•΄μ•Ό ν•˜λŠ” κ²½μš°κ°€ λΉˆλ²ˆν•˜λ‹€.

      κΈ°λŠ₯이 되면 κ·Έλƒ₯ κ·Έκ±° 쓰지 ν•˜κ³  λ„˜μ–΄κ°€μ§€ 말고, λ°˜λ“œμ‹œ Bean 이 무슨 역할을 ν•˜κ³  μ–΄λ–€ λ ˆμ΄μ–΄μ— μ†ν•΄μžˆμ–΄μ•Ό ν•˜λŠ”μ§€ μ–΄λ…Έν…Œμ΄μ…˜μœΌλ‘œ μƒκΈ°μ‹œμΌœμ£Όμž.

    2. XML Config

      λ‹¨λ„μ§μž…μ μœΌλ‘œ λ§ν•˜λ©΄, ν•„μžλŠ” ν•΄λ‹Ή 방법을 μ„ ν˜Έν•˜μ§€ μ•ŠλŠ”λ‹€. ν•˜μ§€λ§Œ 아직도 λ§Žμ€ νšŒμ‚¬λ“€μ˜ μ›Ήμ„œλΉ„μŠ€μ—λŠ” XML Config ν˜•μ‹μ˜ Bean이 λ“±λ‘λ˜μ–΄ μžˆμ„ 수 있고, κ°œμ„  ν•΄μ•Ό λ˜λŠ” ν”„λ‘œμ νŠΈμ—λ„ μžˆμ„ ν™•λ₯ μ΄ 있기 λ•Œλ¬Έμ— 쓸쀄은 λͺ°λΌλ„ β€˜μ½μ„μ€„μ€ μ•Œμ•„μ•Όβ€™ ν•˜λŠ” 등둝 방법이닀.

      μŠ€ν”„λ§ 기반의 ν”„λ‘œμ νŠΈμ—μ„œ, 주둜 μ•„λž˜μ™€ 같은 xml 파일이 쑴재 ν•  것이닀. (파일λͺ…은 λ‹€ λ‹€λ₯Ό μˆ˜κ°€ μžˆλ‹€.) {projectDir}/src/main/resources/application.xml

      주둜 λ‹€μŒκ³Ό 같은 ν˜•μ‹μœΌλ‘œ 무언가 <bean> νƒœκ·Έλ“€μ΄ μ‘΄μž¬ν•œλ‹€.

      <?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
           
          <bean id="testBean" class="com.component.TestBean">
              <property name="name" value="졜재호"/>
          </bean>
      </beans>
      

      λ‹€μŒκ³Ό 같이 xml에 TestBean 등둝 ν›„,

      public class DemoApplication {
           
          public static void main(String[] args) {
              ApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml");
           
              TestBean testBean= ctx.getBean(TestBean.class);
              System.out.println(testBean.getName());
          }
      }
      

      λΆˆλŸ¬μ™€μ„œ Name을 좜λ ₯ν•˜λ©΄, <property> νƒœκ·Έμ—μ„œ μž…λ ₯ν•œ 이름이 좜λ ₯λœλ‹€.

  • Dpendency Injection

    Spring Frameworkμ—μ„œ μ˜μ‘΄μ„± μ£Όμž…(Dependency Injection μ΄ν•˜ DI )μ΄λž€, Bean 으둜 λ“±λ‘λœ 클래슀λ₯Ό Ioc μ»¨ν…Œμ΄λ„ˆλ‘œλΆ€ν„° λ„˜κ²¨λ°›λŠ”κ²ƒμ„ μ˜λ―Έν•œλ‹€. μ ˆλŒ€ λ‘œμ§μƒμ—μ„œ β€˜μƒμ„±β€™ λ˜μ§€ μ•ŠλŠ”λ‹€.

    DI 의 방법은 세가지가 μžˆλŠ”λ° λ‹€μŒκ³Ό κ°™λ‹€.

    1. Field Injection

      μ‹€λ¬΄μ—μ„œ κ°€μž₯ 자주 λ³΄μ΄λŠ” DI 방식이며, 사싀 따지고보면 제일 νŽΈλ¦¬ν•œ 방법이닀. μœ„μ˜ Bean μ„€λͺ…에 있던 μ½”λ“œλ₯Ό 보면, λ‹€μŒκ³Ό 같이 μ‚¬μš©ν•œλ‹€.

      @Service
      public class TestService {
           
       @Autowired
       private TestBean testBean;
           
      }
      

      ν•˜μ§€λ§Œ 이 방법은 μΆ”μ²œν•˜μ§€ μ•ŠμœΌλ©°, μ΄μœ λŠ” μ•„λž˜μ˜ Constructor Injection μ—μ„œ ν›„μˆ ν•˜λ„λ‘ ν•œλ‹€.

    2. Setter Injection

      ν•„μžκ°€ κ°œλ°œμžλ‘œμ„œμ˜ μ—°μ°¨λŠ” μ˜€λž˜λ˜μ§€ μ•Šμ•˜κ³ , κ²½ν—˜λ„ μ μ§€λ§Œ, μ‹€λ¬΄μ—μ„œ ν•œλ²ˆλ„ 보지 λͺ»ν•œ 방식이닀.

      @Service
      public class TestService {
           
      	private TestBean testBean;
           	
      	@Autowired
      	public void setTestBean(TestBean testBean) {
      		this.testBean = testBean;
      	}
      }
      

      ν•΄λ‹Ή 방법도 Field Injection κ³Ό ν•¨κ»˜ μΆ”μ²œν•˜μ§€ μ•ŠλŠ”λ‹€. μ΄μœ λŠ” λ§ˆμ°¬κ°€μ§€λ‘œ ν›„μˆ ν•œλ‹€.

    3. Constructor Injection

      Bean 의 μƒμ„±μžμ—μ„œ μ£Όμž…μ„ λ°›λŠ” 방법이닀. μ½”λ“œμ˜ μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

      @Service
      public class TestService {
           
       private final TestBean testBean;
            
       public void TestService(TestBean testBean) {
          this.testBean = testBean;
       }
      }
      

      Constructor Injection 을 μ‚¬μš©ν•΄μ•Ό ν•˜λŠ” μ΄μœ λŠ” λ‹€μŒκ³Ό κ°™λ‹€.

      1. final μ„ μ–Έ κ°€λŠ₯

        μ²˜μŒλΆ€ν„° μ§€κΈˆκΉŒμ§€ 글을 잘 μ½μ—ˆλ‹€λ©΄ μœ„μ˜ 두 DI κ·Ήλͺ…ν•˜κ²Œ λ‹€λ₯Έ 차이점이 보일것이닀. 그것은 final 선언이 κ°€λŠ₯ν•΄ μ‘Œλ‹€λŠ” 것이닀. 객체λ₯Ό final 둜 μ„ μ–Έν•¨μœΌλ‘œ, λŸ°νƒ€μž„μ—μ„œ ν•΄λ‹Ή 객체의 λΆˆλ³€μ„±μ„ β€˜λ³΄μž₯’ ν•΄ μ€„μˆ˜ μžˆλ‹€.

      2. μˆœν™˜μ°Έμ‘° 방지

        Constructor Injection 방식과, Field Injection λŠ” Bean 을 μ£Όμž…ν•˜λŠ” μˆœμ„œ μžμ²΄κ°€ λ‹€λ₯΄λ‹€. Field Injection μ—μ„œλŠ” Bean 을 생성 ν•œ ν›„, μ£Όμž…ν•˜λ €λŠ” Bean 을 μ°ΎλŠ” 방식이고, Constructor Injection 방식은, Arguments의 Bean을 λ¨Όμ € μ°ΎλŠ”λ‹€. 닭이 먼저냐, 달걀이 λ¨Όμ €λƒμ˜ μ°¨μ΄μ§€λ§Œ, Constructor Injection μ—μ„œλŠ” Runtime으둜 λ„˜μ–΄κ°€κΈ° μ „ μˆœν™˜μ°Έμ‘° μ—λŸ¬λ₯Ό μΊμΉ˜ν•΄λ‚Ό 수 μžˆλ‹€.

      3. ν…ŒμŠ€νŠΈ μ½”λ“œ μž‘μ„± 용이

        Test μ½”λ“œλ₯Ό μž‘μ„± ν•  λ•Œ, Field Injection 방식을 μ‚¬μš©ν•œ Bean 을 ν…ŒμŠ€νŠΈ ν•˜λ €λ©΄, Spring Ioc μ»¨ν…Œμ΄λ„ˆλ₯Ό μ°Έμ‘°ν•΄μ•Όν•˜κ³ , λΆˆλŸ¬μ™€μ•Όν•˜λŠ” μ˜μ‘΄μ„±μ΄ ν•œλ‘κ°œκ°€ μ•„λ‹Œλ°, Constructor Injection λ°©μ‹μ˜ Bean 은 λ‹¨μˆœνžˆ new μ—°μ‚°μžλ₯Ό 톡해 객체λ₯Ό μƒμ„±ν•˜μ—¬(인자둜 μ‚¬μš©λ˜λŠ” Bean은 Mock객체둜 λ„£μ–΄μ£Όμž) ν…ŒμŠ€νŠΈλ₯Ό μˆ˜μ›”ν•˜κ²Œ ν•  수 μžˆλ‹€.

νƒœκ·Έ:

μΉ΄ν…Œκ³ λ¦¬:

μ—…λ°μ΄νŠΈ:

λŒ“κΈ€λ‚¨κΈ°κΈ°