Chapter2. 빈 와이어링(묶기)

2.1 스프링 설정 옵션 알아보기

  • XML에서의 명시적 설정
  • 자바에서의 명시적 설정
  • 내재되어 있는 빈을 찾아 자동으로 와이어링 하기

2.2 자동으로 Bean 와이어링하기

  • 컴포넌트 스캐닝 : @Component, @ComponentScan
  • 오토 와이어링 : @Autowired

2.2.1 발견 가능한 빈 만들기

@Component
public class SgtPeppers implements CompactDisc {
   ...
}

@Configuration
@ComponentScan
public class CDPlayerConfig {
    ...
}

2.2.2 컴포넌트 스캔된 빈 명명하기

@Component("beanName") //Spring 종속적인 어노테이션
or
@Named("beanName")     //JSR-330의 어노테이션이며 Spring의 @Component, @Qualifier와 동일하다.
  • 참고 : @Component는 어떤 스프링이 관리하는 컴포넌트를 나타내는 일반적인 스테레오 타입이다. 좀더 세부적인 유스 케이들을 위하여 @Component의 구체화된 형태로 @Repository, @Service, @Controller들이 있다.
    • @Repository : 퍼시스턴스(persistence) 레이어, 영속성을 가지는 속성(파일, 데이터베이스 등)
    • @Service : 서비스 레이어 (비즈니스 레이어)
    • @Controller : spring mvc 기반의 프리젠테이션 레이어

2.2.3 컴포넌트 스캐닝을 위한 베이스 패키지 셋팅

@ComponentScan("com.kakao.game.helloworld.service")
or
@ComponentScan(basePackages = "com.kakao.game.helloworld.service")
or
@ComponentScan(basePackages = {"com.kakao.game.helloworld.service", "com.kakao.game.helloworld.support"})
or
@ComponentScan(basePackageClasses = {CDPlayer.class, DVDPlayer.class})

2.2.4 오토와이어링 되는 빈의 에너테이션

  • 생성자 주입
    @Component
    public class CDPlayer implements MediaPlayer {
      private CompactDisc cd;

      @Autowired
      public CDPlayer(CompactDisc cd) {
        this.cd = cd;
      }    
      public void play() {
        cd.play();
      }
    }
  • property setter method
    @Autowird
    public void setCompactDisc(CompactDisc cd) {
     this.cd = cd;
    }
  • 일반 method
  • @Autowired 과 @Inject 및 @Resource 비슷하지만 차이가 있음.
    • @Autowired : spring 전용, 타입에 맞춰 연결
    • @Inject :java(JSR)에서 지원, 타입에 맞춰 연결
    • @Resource : java(JSR)에서 지원, 이름으로 연결
    @Autowired
    private Chicken penguin;  //Chicken 타입으로 연결됩니다.

    @Inject
    private Penguin chicken; //Penguin 타입으로 연결됩니다.

    @Resource
    private Chicken penguin;  //penguin 타입으로 연결됩니다만, Chicken 클래스를 자료형으로 두었기에 캐스팅이 되지 않아 에러가 납니다

    @Resource
    private Bird penguin;    //penguin 타입으로 연결되어 호출해보면 penguin 클래스의 값을 호출하는 것을 볼 수 있습니다.

    @Autowired
    @Qualifier("chicken")
    pirvate Brid penguin;   //타입이나 이름에 상관없이 chicken타입으로 연결

2.2.5 자동 설정 검증하기

2.3 자바로 Bean 와이어링하기

2.3.1 설정 클래스 생성 : @Configuration

@Configuration
@ComponentScan(basePackageClasses = {CDPlayer.class,SgtPeppers.class})
public class CDPlayerConfig {
}

2.3.2 간단한 Bean 선언하기 : @Bean

@Configuration
public class CDPlayerConfig {
    @Bean
    public CompactDisc compactDisc() {
        return new SgtPeppers();
    }

    @Bean
    public CDPlayer cdPlayer(CompactDisc compactDisc) {
        return new CDPlayer(compactDisc);
    }
}

2.3.3 JavaConfig 주입

  • 스프링의 모든 빈은 싱글톤으로 생성되므로, 서로 다른 빈에서 같은 인스턴스를 참조할 수 있다.
    @Bean
    public CDPlayer cdPlayer1() {
        return new CDPlayer(sgtPeppers());
    }

    @Bean
    public CDPlayer cdPlayer2() {
        return new CDPlayer(sgtPeppers());
    }

    @Bean
    public CDPlayer cdPlayer3(CompactDisc compactDisc) {
        return new CDPlayer(compactDisc);
    }

    @Bean
    public CDPlayer cdPlayer4(CompactDisc compactDisc) {
        CDPlayer cdPlayer = new CDPlayer();
        cdPlayer.setCompactDisc(compactDisc);
        return cdPlayer;
    }

2.4 빈을 XML로 와이어링하기

XML을 단독으로 사용할 때 특징

  • 생성되는 모든 빈을 XML에서 확인 가능하다.
  • 설정 정보를 코드로부터 분리할 수 있다.
  • 스프링이 제공하는 모든 종류의 빈 설정 메타정보 항목을 지정할 수 있는 유일한 방법이다.
  • 빈의 개수가 많아지면 관리하기 어렵다.

예제

1. 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 http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>

2. 빈 등록하기

<bean id="compactDisc" class="soundsystem.SgtPeppers" />

3. 생성자 주입하기

  • 추후에 argument의 이름이 바뀔 수 있으니 주의해야 한다.
1) constructor-arg
<bean id="cdPlayer" class="soundsystem.CDPlayer">
  <constructor-arg ref="compactDisc" /> // 빈
  <constructor-arg value="Sgt. Pepper's Lonely Hearts Club Band" /> // 리터럴
  <constructor-arg> // 빈 컬렉션
    <list>
      <ref bean="sgtPeppers" />
      <ref bean="whiteAlbum" />
      <ref bean="hardDaysNight" />
      ...
    </list>
  </constructor-arg>
  <constructor-arg> // 리터럴 컬렉션
    <list>
      <value>Sgt. Pepper's Lonely Hearts Club Band</value>
      <value>With a Little Help from My Friends</value>
      <value>Lucy in the Sky with Diamonds</value>
      ...
    </list>
  </constructor-arg>

  <constructor-arg index="0" ref="compactDisc" /> // 순서
  <constructor-arg type="sountsystem.CompactDisc" ref="compactDisc" /> // 타입
  <constructor-arg name="compactDisc" ref="compactDisc" /> // 이름
</bean>
2) c-namespace
<bean id="cdPlayer" class="soundsystem.CDPlayer" c:cd-ref="compactDisc" /> // 이름으로 와이어링
<bean id="compactDisc"
      class="soundsystem.BlankDisc"
      c:_title="Sgt. Pepper's Lonely Hearts Club Band"
      c:_artist="The Beatles" />

<bean id="cdPlayer" class="soundsystem.CDPlayer" c:_0-ref="compactDisc" /> // 순서로 와이어링
<bean id="compactDisc"
      class="soundsystem.BlankDisc"
      c:_0="Sgt. Pepper's Lonely Hearts Club Band"
      c:_1="The Beatles" />

<bean id="cdPlayer" class="soundsystem.CDPlayer" c:_-ref="compactDisc" /> // 하나만 있을 때
<bean id="compactDisc"
      class="soundsystem.BlankDisc"
      c:_="Sgt. Pepper's Lonely Hearts Club Band" />

4. 프로퍼티 주입하기

1) property
<bean id="cdPlayer" class="soundsystem.properties.CDPlayer">
  <property name="compactDisc" ref="compactDisc" />

  <property name="title" value="Sgt. Pepper's Lonely Hearts Club Band" />
  <property name="artist" value="The Beatles" />

  <property name="tracks">
    <list>
      <value>Sgt. Pepper's Lonely Hearts Club Band</value>
      <value>With a Little Help from My Friends</value>
      <value>Lucy in the Sky with Diamonds</value>
      ...
    </list>
  </property>
</bean>
2) p-namespace
<bean id="cdPlayer" class="soundsystem.properties.CDPlayer"
      p:compactDisc-ref="compactDisc" />

<bean id="compactDisc" class="sound system.BlankDisc">
    <p:title="Sgt. Pepper's Lonely Hearts Club Band" />
    <p:artist="The Beatles" />
</bean>

<util:list id="trackList">  
  <value>Sgt. Pepper's Lonely Hearts Club Band</value>
  <value>With a Little Help from My Friends</value>
  <value>Lucy in the Sky with Diamonds</value>
  ...
</util:list>

<bean id="compactDisc"
      class="soundsystem.properties.BlankDisc"
      p:title="Sgt. Pepper's Lonely Hearts Club Band"
      p:artist="The Beatles"
      p:tracks-ref="trackList" />

5. 자동 와이어링

다음과 같은 클래스가 있다고 하자.

public class Hello {
  ...
  public Hello(String name, Printer printer) {
    this.name = name;
    this.printer = printer;
  }
}
1) 이름으로 자동 와이어링
<bean id="printer" class="...StringPrinter" />
<bean id="hello" class="...Hello" autowire="byName"> //
  <property name="name" value="Spring" />
  // <property name="printer" ref="printer" />가 생략되었다. 빈의 이름과 프로퍼티의 이름이 같기 때문에 자동와이어링이 된다.
</bean>
  • 오타 조심
2) 타입으로 자동 와이어링
<bean id="mainPrinter" class="...StringPrinter" />
<bean id="hello" class="...Hello" autowire="byType">
  <property name="name" value="Spring" />
  // <property name="printer" ref="printer" />가 생략되었다. 빈의 타입과 프로퍼티의 타입이 같기 때문에 자동와이어링이 된다.
</bean>
  • 타입이 같은 빈이 두 개 이상 존재하면 쓸 수 없다.
  • 타입 비교가 이름 비교보다 느리다.
3) 여러 빈을 자동 와이어링
  <beans default-autowire="byName"> // 이 아래 모든 빈은 이름으로 자동 와이어링된다.
    <bean>...</bean>
    ...
  </beans>

생성자 주입 vs 프로퍼티 주입

  • 프로퍼티 주입을 더 많이 쓰는 이유
    1. 역사적인 이유 - 초창기에 프로퍼티 주입에 좀 더 집중된 구조 - 때문에
    2. 프로퍼티 주입으로 더 많은 설정이 가능하기 때문에
  • 유효한 객체를 만들기 위해서는 생성자 주입을 더 신경써주어야 한다.

2.5 설정 가져오기와 믹싱하기

1) JavaConfig끼리 참조하기

@Import({CDConfig.class, CDPlayerConfig.class})

2) XML끼리 참조하기

<import resource="cd-config.xml" />

3) JavaConfig로 XML 설정 참조하기

@ImportResource("classpath:cd-config.xml")

4) XML 설정에서 JavaConfig 참조하기

<bean class="soundsystem.CDConfig" />

results matching ""

    No results matching ""