본문 바로가기

개인적으로 공부한 것을 정리해 놓은 블로그입니다 틀린 것이 있으면 댓글 부탁 드립니다!


SPRING FRAMEWORK

Spring core 스터디 4 - 어노테이션을 활용한 DI (@Autowired)

반응형

어노테이션은 코드의 메타데이터를 설정해주는 자바의 기능이다  xml을  사용하는 방식에서 더 쉽게 DI를 적용하기 위해 어노테이션을 활용하여 DI를 구현하게 되었고 @Autowired를 사용한다.  

 

@Autowired

 

Xml 파일로 DI 를 지시할 떄 사용했던 <property>를 대신한다. 

 

의존객체의 setter 메서드에 명시해놓으면 <property>에 적어놓지 않아도 스프링이 알아서 의존객체를 찾아 주입해준다.

 

xml namespace에 context를 체크하고 아래의 코드를 추가 해줘야 한다.

 

context namspace 추가

<!-- 어노테이션 기반으로된 config임을 선언함 -->
<context:annotation-config/>

 

Autowired를 사용한 DI

 

public class GridExamConsole implements ExamConsole {
    private Exam exam;
    
    public GridExamConsole(Exam exam) {
        this.exam = exam;
    }
    
    @Override
    public void print() {
        System.out.println("total  |  avg");
        System.out.printf("%3d    |  %3.2f\n",exam.total(),exam.avg());
    }
    
    @Autowired
	@Override
	public void setExam(Exam exam) {
		this.exam = exam;
	}
}

 

 

위처럼 의존객체  setter 메서드에 @Autowired를 명시하면 객체생성시 @Autowired 어노테이션을 보고 스프링이 자동으로 의존 객체를 생성 하고 주입해 준다.

 

 

@Autowired의 동작 방식

 

 Autowired는 클래스 타입을 기준으로 동작한다. 위의 예제 코드처럼 setExam이라는 의존객체 주입 메서드에 @Autowired가 붙어 있다면  IoC 컨테이너에서 우선 타입이 Exam인 bean을 찾아내서 주입해준다.

만약 같은 타입으로 등록된 bean이 여러개라면 다음으로는 주입 받는 변수명과 bean의 id를 비교하여 주입한다. 

만약 변수명도 모호하다면 @Qualifier("bean의 id")를 사용하여 bean의 id를 지정해 줄 수있다.

 

//생성하는 객체의 의존객체 주입 setter 메서드
@Autowired
@Override
public void setExam(Exam exam) {
	this.exam = exam;
}


//아래와 같이 bean의 클래스 타입이 같을 경우 bean의 아이디와 setter메서드의 변수명 비교
//첫번째 것이 주입된다.
<bean id="exam" class="src.spring.di.entity.NewlecExam" p:kor="20" p:eng="30" p:com="30" p:math="40"/>
<bean  class="src.spring.di.entity.NewlecExam" p:kor="10" p:eng="20" p:com="40" p:math="50"/>

//bean의 아이디명도 모호할 경우
<bean id="exam1" class="src.spring.di.entity.NewlecExam" p:kor="20" p:eng="30" p:com="30" p:math="40"/>
<bean id="exam2" class="src.spring.di.entity.NewlecExam" p:kor="10" p:eng="20" p:com="40" p:math="50"/>

//@Qualifier("bean의 id")로 주입객체를 지정할 수 있다. 

@Autowired
@Qualifier("exam1")
@Override
public void setExam(Exam exam) {
	this.exam = exam;
}

 

 

인젝션의 3가지 방법

 

public class GridExamConsole implements ExamConsole {
    
    1.
    @Autowired <---기본생성자를 통한 DI
    private Exam exam;
    
    2.
    @Autowired <---생성자를 통한 DI
    public GridExamConsole(Exam exam) {
        this.exam = exam;
    }
    
    @Override
    public void print() {
        System.out.println("total  |  avg");
        System.out.printf("%3d    |  %3.2f\n",exam.total(),exam.avg());
    }
    
    3.
    @Autowired <---setter를 통한 DI
	@Override
	public void setExam(Exam exam) {
		this.exam = exam;
	}
}

 

1.기본생성자를 통한 DI

 

2.생성자를 통한 DI

 -생성자의 파라미터가 여러개가 될 수 있음으로 @Qualifier를 파라미터에 직접 적어줘야 한다.

 

3.setter를 통한 DI

 

@Autowired의 required 속성

 

@Autowired를 통해 주입 객체를 찾지 못하는 경우 bean으로 존재하지 않는 경우 에러가 나게된다.

null 일 경우를 대비하여 @Autowired(required = false)로 지정해놓으면 찾는 의존 객체가 없을 경우에도 객체가 생성된다 

 

public class InlineExamConsole implements ExamConsole {
	
	@Autowired(required = false)
	@Qualifier("exam1")
    private Exam exam;
    
    public InlineExamConsole() {
  
    }
    
    public InlineExamConsole(Exam exam) {
        this.exam = exam;
    }

    @Override
    public void print() {
    	if(exam == null) {
    		System.out.println("의존객체가 없습니다.");
    	}else {
    		System.out.printf("total is %d, avg is %f\n",exam.total(),exam.avg());    		
    	}
    }
    
   
	@Override
	public void setExam(Exam exam) {
		this.exam = exam;
	}
}

 

위 코드처럼 required = false로 해두면는 의존객체가 없을때에도 대처가 가능하다.

 

 

 

반응형