본문 바로가기

프로그래밍/Spring

애노테이션(Annotation을 이용한 의존객체 주입

의존객체 자동 주입

스프링에서는 개발자가 일일히 의존정보를 설정하지않아도 스프링 컨테이너가 자동으로 스프링 빈 객체간의 의존을 설정해주는 기능을 제공한다. 의존객체를 자동을 주입하기 위해서 사용하는 방법이 몇가지 있는데, @Autowired, @Resource, @Inject 애노테이션을 이용하여 설정할 수 있다.
애노테이션 기반의 의존객체 자동주입을 사용하기위해선 xml 파일에 <context:annotation-config>태그를 추가해야 한다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"    <!--추가 -->
       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
            http://www.springframework.org/schema/context               <!--추가 -->
            http://www.springframework.org/schema/context/spring-context.xsd">  <!--추가 -->

    <context:annotation-config/><!--추가 -->

</beans>

@Autowired

@Autowired 애노테이션은 의존 관계를 자동으로 설정할 때 사용되며 생성자, 필드, 메서드에 적용 가능하다.

1. 프로퍼티 필수 여부 지정(required)

스프링은 @Autowired 애노테이션을 발견하면 그에 해당하는 빈 객체를 찾아서 설정하지만 해당하는 타입의 빈 객체가 없으면 애플리케이션을 구동하지 못하고 에러가 발생한다.

@Service
public class BookService {
    BookRepository bookRepository;

    @Autowired
    public BookService(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }
}

public class BookRepository {
}

실행결과

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.giantdwarf.book.BookService required a bean of type 'com.giantdwarf.book.BookRepository' that could not be found.


Action:

Consider defining a bean of type 'com.giantdwarf.book.BookRepository' in your configuration.

이 경우 BookRepository를 빈으로 등록해주면 BookService에 주입할 수 있어서 해결되나 의존성이 반드시 필요한게 아니라면 @Autowired의 required 속성을 false로 지정하면 된다(default값은 true)

@Service
public class BookService {

    BookRepository bookRepository;


    @Autowired(required = false)
    public void setBookRepository(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }
}

public class BookRepository {
}

2. @Qualifier 애노테이션을 이용한 설정 제한

동일한 타입의 빈 객체가 여러개인 경우 어떤 객체를 주입해야 하는지 알수없어서 애플리케이션 구동을 실패하게된다.

@Service
public class BookService {

    @Autowired
    BookRepository bookRepository; //MyBook인지 UserBook인지 알수 없음
}

public interface BookRepository {
}

@Repository
public class MyBookRepository implements BookRepository {
}

@Repository
public class UserBookRepository implements BookRepository {
}

실행결과

Description:

Field bookRepository in com.giantdwarf.book.BookService required a single bean, but 2 were found:
    - myBookRepository: defined in file [/Users/yangseung-in/IdeaProjects/demospring5/target/classes/com/giantdwarf/book/MyBookRepository.class]
    - userBookRepository: defined in file [/Users/yangseung-in/IdeaProjects/demospring5/target/classes/com/giantdwarf/book/UserBookRepository.class]


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

실행결과에 나온대로 @Primary 애노테이션을 주로 사용하고싶은 빈에 사용하여 우선순위를 높여 지정할 수도 있고, @Qualifier 애노테이션을 추가해서 사용할 수 있다.

@Service
public class BookService {

    @Autowired @Qualifier("MyBookRepository")
    BookRepository bookRepository; 
}

public interface BookRepository {
}

3. @Resource 애노테이션을 이용한 설정 제한

@Resource 애노테이션 역시 알맞은 빈 객체를 할당하나 @Autowired와의 차이점은 @Autowired는 타입을 기준으로 참조할 빈 객체를 선택하고 @Resource는 이름을 기준으로 빈 객체를 선택한다.

@Service
public class BookService {

    @Resource(name = "myBookRepository")
    BookRepository bookRepository;

}

4. @Inject 애노테이션을 이용한 설정 제한

@Inject 애노테이션 역시 @Autowired와 마찬가지로 생성자, 필드, 메서드에 적용할수 있으나 @Inject 애노테이션은 반드시 컨테이너에 주입할 빈이 존재해야한다.

'프로그래밍 > Spring' 카테고리의 다른 글

스프링 부트의 오류처리(Error Handling)  (0) 2020.07.05
스프링부트의 자동설정  (0) 2020.06.21
스프링 AOP  (0) 2020.04.19
빈의 스코프  (0) 2020.03.18
제어 역전(IoC)와 의존성주입(DI)  (0) 2020.03.12