@Autowired란
각 상황에 맞는 Bean을 IOC 컨테이너에서 자동으로 주입하게 만드는 것
@Autowired를 사용하는 이유 : 편리함
@Autowired 사용 전
public class AutowiredService {
private Autowiredrepository autowiredrepository;
public AutowiredService(Autowiredrepository autowiredrepository){
this.autowiredrepository = autowiredrepository;
}
}
AutowiredRepository를 전달반고 변수로 할당함
그럼 repository를 service 에 주입하기 위해서
public class AutowiredService {
private Autowiredrepository autowiredrepository;
public AutowiredService(Autowiredrepository autowiredrepository){
this.autowiredrepository = autowiredrepository;
}
}
이렇게 xml로 bean 설정을 해주어야 함
아니면 java class에 Bean 설정을 해주어야 함
@Configuration
public class ApplicationConfig {
@Bean //메소드
public Autowiredrepository autowiredrepository(){
return new AutowiredRepository();
}
@Bean
public AutowiredService autowiredService(){
return new AutowiredService(AutowiredRepository());
}
}
@Autowired를 사용하면 객체 의존성을 가지는 부분에 annotation을 사용하면 된다
@Service
public class AutowiredService {
private Autowiredrepository autowiredrepository;
@Autowired
public AutowiredService(Autowiredrepository autowiredrepository){
this.autowiredrepository = autowiredrepository;
}
}
repository에 annotation을 달아서 Bean으로 등록해주고 의존성 주입이 되게 만들면 된다
@Repository
public interface Autowiredrepository {
}
직접적으로 사용하는 것보다는 스프링 ioc에서 디펜던시를 주입하는 방법이 더 많이 쓰임
TMI : Spring 4.3부터 클래스에 생성자가 하나이고, 생성자로 주입받는 레퍼런스 변수들이 빈으로 등록되어있다면 자동으로 주입해주도록 기능이 추가 됨
@Autowired를 생략하여 사용 가능함
사용할 수 있는곳
Field Setter 생성자
@Autowired-1
필드에 바로 주입을 받는 방법
(final을 붙이면 안된다 / 인스턴스를 무조건 붙여야 하는 것이라서 붙이면 안된다 )
@Autowired
Private MainRepository main;
@Autowired-2
Setter에 @Autowired를 붙이는 방법
final을 붙이면 안된다
@Autowired
Public void SetMain(MainRepository main){
this.main = main;
인스턴스를 만든 후 setter 를 통해 ioc 컨테이너의 빈 중 MainRepository 타입을 찾아서 넣어준다
- final이란 : 정의하고 변경하지 못하도록 할때 사용
상수, 클래스, 메서드 3가지 경우에 사용 가능
1. 상수 : final 타입 상수명
final int cnt;
final int cnt=1;
cnt =10
//이렇게 사용을 하면 에러가 난다
2. 메서드 : final 반환형 메서드명 (매개변수){}
ovrriding을 못하게 만든다
class study{
public final void study1(){
//내용정의
}
}
public class Main extends study{
//public test2(){} compile error: final method는 오버라이딩 못함
}
3.클래스 상속 : final class 클래스{}
final class Test{
int test;
}
class에 Final 키워드는 상속을 못하게 할때 사용
final을 사용한 test는 객체를 생성할 수 없다
final의 장점은 객체를 바꿔치기 할 수 없다
@Autowired-3
레퍼런스에서 권장하는 방법 -> 생성자
필수적으로 사용해야 하는 레퍼런스 없이는 인스턴스를 만들지 못하도록 강제 할 수 있음
Private final MainRepository main;
Public void SetMain(MainRepository main){
this.main = main;
}
[생성자를 통한 의존성 주입의 장점]
-의존성 주입이 필요한 필드를 final 로 선언하여 Immutable 하게 사용가능
-의존관계가 설정되지 않으면 객체 생성이 불가능하기 때문에 null을 주입하지 않는 이상 NullPointError 를 방지할 수 있다
-테스트코드 작성 용이(필드 인젝션이면 단위테스트시 의존관계를 가지는 객체를 생성해서 주입할 수가 없음 / 생성자를 사용해 작성되었다면 객체를 생성할때 원하는 구현체를 넘겨주면 되고 구현체를 넘겨주지 않으면 객체 생성 자체가 불가능하기 때문에 테스트에 용이)
단, 순환참조가 발생할 수 있음
(순환 참조가 발생했을 때 가장 좋은 해결책은 다시 설계 하는 것ㅎㅎ)
A와 b가 서로를 참조한다 (생성자 인젝션 사용)
둘다 생성이 되지 않는다. -> 의존성 주입이 안되면 어플리케이션이 뜨지 않는다
컨테이너가 빈을 생성하는 시점에서 객체생성에 사이클 관계가 생기기 때문
(필드 주입이나, 수정자 주입은 객체 생성 시점에 순환참조가 일어나는지 아닌지 알 방법이 없다.)
이런 경우 생성자 인젝션 대신에 Setter 인젝션이나 field 인젝션을 사용하면 상호 참조하는 의존성 문제 해결 가능
'Spring' 카테고리의 다른 글
페이징처리 (0) | 2021.05.10 |
---|---|
hibernate란? (0) | 2021.05.09 |
Spring VS Node.js (0) | 2021.04.25 |