뉴렉쳐 스프링 프레임워크 정리

[14강] @Autowired의 위치와 Required 옵션

째로스 2023. 6. 10. 16:56

1. 기본 형식

public class InlineExamConsole implements ExamConsole
{
	private Exam exam;

    public InlineExamConsole(){
        System.out.println("constructor");
    }

    public InlineExamConsole(Exam exam){
        System.out.println("overloaded constructor");
        this.exam=exam;
    }
	
	@Override
    public void setExam(Exam exam){
        System.out.println("setter");
        this.exam=exam;
    }
    
	@Override
	public void print(){
		System.out.printf("total is %d, avg is %f\n",exam.total(), exam.avg());
	}
}

여기서 Annotation을 사용하여 객체를 주입하기 위해서 @Autowired가 들어갈 수 있는 자리는 총 4군대로

변수 exam 앞, 기본 생성자 앞, 오버라이드된 생성자 앞, 세터 앞이다.

<!--pom.xml-->
<bean id="exam1" class="sprint.di.entity.NewLecExam" p:kor="10" p:eng="10"/>
<bean id="exam2" class="sprint.di.entity.NewLecExam" p:kor="20" p:eng="20"/>

xml 파일에 위와같은 빈 객체들이 입력된 상테에서 진행된다.

 

2. setter 앞에 @Autowired 어노테이션을 붙인 경우

private Exam exam;

public InlineExamConsole(){
	System.out.println("constructor");
}

public InlineExamConsole(Exam exam){
	System.out.println("overloaded constructor");
    this.exam=exam;
}

@Autowired
@Qualifier("exam2")
public void setExam(Exam exam){
	System.out.println("setter");
    this.exam=exam;
}

위 같이 setter 앞에 @Autowired가 붙는다면 먼저 기본생성자를 통해 객체를 생성하고 setter가 실행되기 때문에

constructor
setter

라는 결과가 출력된다.

이 때 만약 기본생성자가 작성되어 있지 않다면 오류가 발생한다.

기본 생성자를 작성하지 않고도 오류가 발생하지 않으려면 오버라이드된 생성자를 작성하지 않아야 한다.

그래야 컴파일러가 자동으로 기본 생성자를 생성해낼 것이기 때문이다.

 

3. 변수 앞에 @Autowired 어노테이션을 붙인 경우

@Autowired
@Qualifier("exam2")
private Exam exam;

public InlineExamConsole(){
	System.out.println("constructor");
}

public InlineExamConsole(Exam exam){
	System.out.println("overloaded constructor");
    this.exam=exam;
}

public void setExam(Exam exam){
	System.out.println("setter");
    this.exam=exam;
}
construct

라는 결과가 출력된다.

setter가 실행되지 않고 해당 변수에 객체만을 주입하기 때문이다.

 

4. 오버라이드된 생성자에 @Autowired 어노테이션을 붙인 경우

private Exam exam;

public InlineExamConsole(){
	System.out.println("constructor");
}

@Autowired
public InlineExamConsole(
	@Qualifier("exam1") Exam exam1,
	@Qualifier("exam2") Exam exam2){
	System.out.println("overloaded constructor");
	this.exam=exam1;
}

public void setExam(Exam exam){
	System.out.println("setter");
    this.exam=exam;
}

오버라이드된 생성자에는 1개 이상의 매개변수가 들어오기 때문에, 각각의 매개변수에 특정 이름을 명시하는

@Qualifier가 필요하다.

같은 타입의 매개변수가 여러개 입력될 수도 있기 때문이다.

overloaded constructor

setter는 실행되지않으며 출력값을 위와 같다.

 

5. @Autowired(required = false)

그런데 xml 파일에 baen 객체가 입력되지 않은 경우에는 위 코드들에서 오류가 발생한다.

이를 막기 위해서는 어떻게 해야할까?

 

Autowired에 required= false를 적용시키면 이를 해소시킬 수 있다.

public class InlineExamConsole implements ExamConsole
{
	@Autowired(required=false)
	@Qualifier("exam2")
	private Exam exam;

    public InlineExamConsole(){
        System.out.println("constructor");
    }

    public InlineExamConsole(Exam exam){
        System.out.println("overloaded constructor");
        this.exam=exam;
    }
	
	@Override
    public void setExam(Exam exam){
        System.out.println("setter");
        this.exam=exam;
    }
    
	@Override
	public void print(){
		if(exam==null)
			System.out.printf("total is %d, avg is %f\n",0, 0);
		else
			System.out.printf("total is %d, avg is %f\n",exam.total(), exam.avg());
	}
}

만약 xml에 해당하는 객체가 없는 경우, exam은 null값을 갖게되며 오류가 발생하지 않는다.

위처럼 print 함수 호출 시에 다른 분기를 만들어 낼 수도 있다.