본문 바로가기
✨ Back-end/Spring-Boot

[Spring] DI(의존성 주입) @Autowired, @Resource, @Controller, @Service

by 환풍 2023. 3. 15.
728x90
반응형

DI(의존성 주입)을 하는 방법

 

1. 프로그램 실행 시 필요할 것 같은 객체는 모두 만들어준다.
2. 만들어진 객체 중 필요한 객체를 의존성 주입시킨다.

 

  • 프로젝트 생성시 기본 패키지 안에 있는 모든 클래스는 스프링이 자동으로 객체를 생성하는 자격이 된다.
  • 객체 생성 어노테이션을 사용하여 객체를 생성한다. ( @Component, @Controller, @Service, @Repository 등)

 

@Component 스프링 초창기 버전에 사용했던 어노테이션이다. 초창기에는 밑에 있는 어노테이션들이 없었다.

이 클래스가 왜 객체를 만들어야하는지 애매모호했다. 그래서 세분화 시켰다.

역할을 부여하기 위해 세분화 한 것@Controller, @Service, @Repository 이다.

 

 

스프링 mapper에서 쿼리 작성을 모두 마쳤다고 가정해보자.

MemberService 인터페이스로 넘어와 쿼리 구현을 위한 메서드를 만들어준다.

인터페이스는 내부에 메소드 본체를 가질 수 없다.

메소드 헤더만 정의하고 이를 구현하는 클래스에서 본체를 구현할 수 있다.

이런 인터페이스로 구성 시 확장성과 유연성이 좋아진다. 소켓과도 같은 개념이라 쉽게 교체하거나 유지보수가 쉬워진다. 

 

MemberServiceImpl (Impl => "구현했다") 클래스에서 위 인터페이스의 상속을 받았다. 이때 사용된 것이 @Service이다.

해당 클래스가 Service라는 것을 표현하기 위해 어노테이션 @Service로 정의한다.

오버라이드를 이용해 메소드 본체를 작성할 수 있다.

 

밑의 private SqlSessionTemplate sqlSession; 객체를 선언만 하였지만,

스프링에서는 @Autowired를 이용하여 자동으로 객체를 만들어주고 사용할 수 있다. 

단, @Autowired는 자료형을 기반으로 객체를 넣어주기 때문에 동일한 자료형이 두개 이상이면 오류가 난다.

예시)

1
2
3
4
5
6
7
8
9
10
11
//예시
@Component
class Avante implements Car{...} -> Avante avante = new Avante();
 
@Component
class Sonata implements Car{...} -> Sonata sonata = new Sonata();
 
@Autowired
private Car c;
 
//private Car c;는 Sonata, Avante 두개 들어올 수 있어 오류.
cs

이러한 상황을 막기 위해 @Resource( )를 사용할 수 있다.

1
2
@Resource(name="avante")
private Car c;
cs

이렇게 바꿔주면 Car 인터페이스에서 avante를 지칭해서 들고 올 수 있기 때문이다.

@Resource( ) 만들어진 객체 명을 기준으로 의존성 주입을 시킨다.

 

인터페이스는 implements를 해주는 것들이 많으므로, 이처럼 지칭을 해줘야한다.

인터페이스를 사용하면 이렇게 Resource를 사용하자.

 

@Autowired vs @Resource 차이점

@Autowired 는 타입, 자료형을 이용하여 의존성을 주입한다. (Class로 Bean지정.)
[ 생성자, 필드, 메서드 모두 적용 가능 ]

@Resource 는 빈 이름, 객체 명을 이용하여 의존성을 주입한다.  (Name으로 Bean지정.)
[필드, 메서드에만 적용 가능]

 

728x90
반응형

댓글