티스토리 뷰

Spring

스프링을 활용한 의존성주입 - 2

사용자 엔꾸꾸 2019. 5. 1. 17:18

스프링을 활용한 의존성주입 - 2

  • 지난시간에는 의존성주입과 , 스프링을 활용한 빈등록방법에 대해 알아보았다.

  • 지난 내용이 궁금하다면 하단링크 참고

https://pupupee9.tistory.com/4

이번 포스트에서는 스프링을 활용한 의존성주입방법에 대해 살펴보자.

의존성 주입방법

  • 스프링을 활용한 의존성 주입방법에는 크게 3가지가 있다.
  1. XML을 활용한 의존성 주입방법

  2. JavaConfig를 활용한 의존성 주입방법

  3. 애노테이션을 활용한 의존성 주입방법

위 세가지 방법중 애노테이션을 활용한 의존성주입방법이 가장 쉽고 많이 사용할 방법이다. (물론 회사마다 다르다..)

XML을 활용한 의존성 주입방법

스프링을 활용한 의존성 주입은 생성자를 통한 의존성 주입 , 속성을 활용한 의존성주입을 모두 지원한다.

지난시간 사용한 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">

 <bean id="helloService" class="me.june.service.HelloService"></bean>
 <bean id="helloController"  class="me.june.controller.HelloController"></bean>
</beans>
class HelloController {
     HelloService helloService;
}
class HelloService {

}

다음과 같이 XML 파일에 HelloService 와 HelloController가 빈으로 등록 되어있다.

HelloController는 HelloService에 의존적인 관계이다.
HelloController에 존재하는 helloService객체를 스프링 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">

 <bean id="helloService" class="me.june.service.HelloService"></bean>
 <bean id="helloController"  class="me.june.controller.HelloController">
 <property name="helloService" ref="helloService"></property>
 </bean>
</beans>

HelloController 설정부분에 property 정보가 추가되었다.

property태그를 잠깐 살펴보자.

<property name="helloService" ref="helloService"></property>
  • name : 해당 빈의 프로퍼티명을 의마한다.
  • ref: 해당 프로퍼티로 주입할 빈의 참조를 의미한다.

helloService라는 ID로 HelloService를 빈으로 등록했기때문에
HelloController를 빈으로 등록함과 동시에 helloService의 참조정보를 활용하여 의존성을 주입한것이다.

JavaConfig를 활용한 의존성 주입방법

이번에는 JavaConfig를 활용한 의존성 주입방법을 살펴보도록 하자.

눈으로 확인하기 위해 HelloController의 코드를 조금 수정하였다.
수정된 코드는 다음과 같다.

class HelloController {
     HelloService helloService;

     public HelloService getHelloService() {
         return helloService;
     }

     public void setHelloService(HelloService helloService) {
         this.helloService = helloService;
     }
}

그리고 이어 JavaConfig를 활용한 코드이다.

@Configuration
class WebConfig {
   @Bean
   public HelloService helloService() {
           return new HelloService();
   }

   @Bean
   public HelloController helloController() {
       HelloController helloController = new HelloController();
       helloController.setHelloService(helloService());
       return helloController;
   }
}

결과는 XML을 활용한 의존성 주입과 동일한 결과가 나타난다.

  • 여기서 잠깐 !

  • 간혹가다 이런 친구들이 있다.

  • 위에서 HelloService 를 빈으로 등록했는데 HelloController를 등록하는 부분에서 해당 빈의 참조를 가져오는것이 아니라 빈 등록 메서드를 호출하는데
    ‘HelloService를 빈으로 등록된것과 , HelloController에 주입된 HelloSerivce가 다른객체 아닌가요 ? ‘

이런 친구들을 위해 테스트코드를 준비했다.
다음 코드와 결과를 살펴보도록하자.

@RunWith(SpringRunner.class)
@SpringBootTest
class DemoWebMvcApplicationTests {

   @Autowired
   HelloService helloService;

   @Autowired
   HelloController helloController;

   @Test
   public void contextLoads() {
       System.out.println("helloService = " + helloService);
       System.out.println("helloController's helloService = " + helloController.getHelloService());

      assertThat(helloService).isEqualTo(helloController.getHelloService());
   }

}

@Autowired 애노테이션은 바로 다음에 설명이 나오니 일단은
‘의존성주입을 해주는 애노테이션’ 이라고만 알아두자.

지금은 빈으로 등록한 HelloService와 HelloController에 주입된 helloService가 같은지 테스트하기때문에 테스트에만 집중하자.

테스트 결과는 다음과 같이 동일하다.

애노테이션을 활용한 의존성 주입방법

이번에는 애노테이션을 활용한 의존성 주입방법을 알아보자.

애노테이션을 활용한 의존성 주입방법은 크게 두가지로 나뉜다.

  1. @Autowired
  2. @Resource

여기서 Autowired , Resource의 차이를 간단하게 살펴보고 가도록하자.

@Autowired

  • 스프링 프레임워크에서 제공
  • type을 먼저 찾고 , 없다면 name으로 찾는다.
  • @Qualifier 를 활용하여 name으로 강제하는 방법이 존재한다.

@Resouce

  • 자바 표준
  • name을 먼저찾고, 없다면 type으로 찾는다.
@Autowired 를 활용한 의존성 주입방법

@Autowired는 위의 테스트코드에서 잠깐 등장했지만
코드를 보며 다시한번 살펴보겠다.

@Controller
class HelloController {

   @Autowired
   HelloService helloService;

}

@Service
class HelloService {

}
  • 먼저 @Service 애노테이션으로 HelloService 가 빈으로 등록된다.

  • @Controller로 인해 HelloController를 빈으로 등록한다.

  • HelloController에 HelloService라는 의존관계가 존재한다.

  • HelloController를 빈으로 등록하기전 HelloSerivce를 @Autowired로 의존성 주입을 시도한다.

  • HelloService가 빈으로 등록되어 있기때문에 의존성이 주입되고, HelloController가 빈으로 등록된다.

  • @Autowired 애노테이션은 생성자와 속성주입 메서드에도 사용이 가능하다.

  • 다음 코드를 한번 살펴보자.

public class HelloController {

     HelloService helloService;

     @Autowired
     public void setHelloService(HelloService helloService) {
         this.helloService = helloService;
     }
}

public class HelloController {

     HelloService helloService;

     @Autowired
     public HelloController(HelloService helloService) {
         this.helloService = helloService;
     }
}

위는 속성주입 메서드를 통해 의존성을 주입받는것이고, 아래는 생성자를 통해 의존성을 주입받는것이다.

스프링 4.3 이후부터는 생성자가 하나만 존재하고 , 해당 클래스가 빈으로 등록되어있다면 @Autowired를 생략 할 수 있다.

코드는 다음과 같이 사용할 수 있다.

public class HelloController {

     HelloService helloService;

     public HelloController(HelloService helloService) {
         this.helloService = helloService;
     }
}
  • Q. 생성자 주입을 왜 사용하나요 ?

속성주입 메서드나 생성자주입을 사용하면 코드가 더 길어지기만 하고,
속성주입을 활용하면 매 필드마다 @Autowired만 사용하면되는데…
별로 안좋은것 같아요…

  • A. 생성자 주입을 사용하는이유

  • 생성자 주입을 사용하는 이유는 다음과같다.

    • 의존성이 많아질수록 생성자 인자가 늘어나 잘못된 설계인지 시각적으로 드러난다.

    • 순환참조 관계시 예외가 발생하며 빈으로 등록되지않는다 (잘못된 설계)

    • 순환 참조 관계란 ?

    • AService 와 BService가 존재하는데 AService는 BService를 , BService는 AService를 서로 참조하는 관계를 순환 참조 관계라고한다.

    • 스프링 4.3 이상인 경우 @Autowired를 생략할 수 있다.

    • 최근 스프링은 애노테이션을 최대한 걷어내려는 노력을 많이 하고있다.

    • 스프링의 철학 중 하나가 스프링에 의존적이지 않은 코드를 만드는것이다.

필자는 생성자주입을 선호한다.

의존관계가 늘어날때마다 생성자를 수정해야하는 불편함이 있다면 Lombok 을 활용해보자.

@Controller
@AllArgsConstructor
public class HelloController {

     HelloService helloService;

}

@Controller
@RequiredArgsConstructor
public class HelloController {

     HelloService helloService;

}

롬복은 사용시 주의해야할점이 존재한다.
권남이님 포스트참조
http://kwonnam.pe.kr/wiki/java/lombok/pitfall

@Resource 를 활용한 의존성 주입방법

이번에는 @Resource를 활용한 의존성 주입방법에 대해 알아보자.

@Resource를 활용한 의존성 주입은 다음과 같은 방법을 주로 사용한다.
코드를 살펴보자

@Service
class HelloService {

}

@Controller
class HelloController {

     @Resource(name="helloService")
     HelloService helloService;
}
  • TIP
    • 스프링에서 제공하는 애노테이션을 이용하여 빈등록시 (@Service, @Controller 등..) 빈의 이름은 기본적으로 카멜케이스 규약을 따른다.
    • 예로들면 HelloService를 빈으로 등록한다고하자, 빈으로 등록시 기본규약에 따라 helloService 라는 이름으로 등록되는것이다.
    • 하지만 팀 내 협업을 위해 명시적인 방법을 선호하는경우에는 다음과 같은 방법으로 빈을 등록하기도한다.
@Service("helloService")
class HelloService {

}

오늘은 스프링을 활용한 의존성 주입에 대해 간단히 살펴보았다.
부족한 내용들도 있지만 도움이 되었기를 바란다.

다음 포스트에서는 스프링 AOP에 대해 알아보도록 하자

'Spring' 카테고리의 다른 글

Spring - PSA  (0) 2019.05.19
스프링 AOP - 2  (0) 2019.05.12
스프링 AOP -1  (0) 2019.05.04
스프링을 활용한 의존성주입 - 2  (0) 2019.05.01
스프링을 활용한 의존성주입 - 1  (0) 2019.04.28
DI - 의존성주입  (0) 2019.04.28
댓글
댓글쓰기 폼
공지사항
Total
75,653
Today
169
Yesterday
201
링크
TAG
more
«   2021/12   »
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
글 보관함