Study/spring

@Autowired vs @Inject vs @Resource

에디개발자 2021. 2. 18. 00:17
반응형

가장 많이 사용하는 @Autowired는 뭘까? 그와 비슷한 @Inject, @Resource는 무엇일까?

오늘 재직중인 회사에서 재미있는 여러가지 키워드를 들었습니다. 궁금한 건 못참으니 학습하여 정리해보겠습니다.

나를 닮았다고 한다...

먼저 위에 3가지의 공통점은 의존 관계를 맺어주는 것을 말합니다. 해당 애노테이션을 사용한 후 클래스를 선언하면 작성한 클래스와 작성된 클래스는 의존 관계가 맺어지게 됩니다.

@Component
public class Load {
    @Autowired
    private SuperCar superCar;   // superCar class DI

    @Inject
    private GoodCar goodCar;   // GoodCar class DI
}

 

다음으로 3가지의 차이점으로 아래의 표를 참조해주세요.

  @Autowired @Inject @Resource
범용 Spring Java Java
연결방식 Type Type Name

 

먼저 비교하기에 앞서 코드 아키텍쳐를 살펴보겠습니다.

Car : Parent Class

SuperCar : Car Class를 상속받은 Child Class / print 메서드를 오버라이딩하여 print 변경

GoodCar : Car Class를 상속받은 Child Class / print 메서드를 오버라이딩하여 print 변경

public class Car {
    public void print() {
        System.out.println("Car");
    }
}
@Component
public class SuperCar extends Car {
    @Override
    public void print() {
        System.out.println("SuperCar");
    }
}
@Component
public class GoodCar extends Car{
    @Override
    public void print() {
        System.out.println("GoodCar");
    }
}

 

@Autowired vs @Inject

차이점 

@Autowired는 Spring Framework에서 제공합니다. 

import org.springframework.beans.factory.annotation.Autowired

@Inject는 Java에서 제공합니다.

import javax.inject.Inject

 

공통점

연결하는 방식이 Class Type으로 동일합니다. 선언한 Class Type으로 의존 관계가 성립되어집니다. 아래의 예제 코드를 참조해주세요.

@Component
public class Load {
    @Autowired
    private SuperCar goodCar;   // superCar class DI

    @Inject
    private GoodCar superCar;   // GoodCar class DI

    public void superCarPrint() {
        goodCar.print();    // superCar print
    }

    public void GoodCarPrint() {
        superCar.print();   // goodCar print
    }
}    

 

@Inject vs @Resouce

차이점

연결하는 방식이 다릅니다. @Inject은 위에서 보셨듯이 Class Type으로 의존관계를 맺지만 @Resource는 선언된 name으로 의존관계를 맺습니다. 아래의 예제코드를 참조해주세요.

@Component
public class Loads {

    @Resource
    private Car superCar;   // SuperCar Class DI

    @Resource
    private Car goodCar;    // GoodCar Class DI

    public void superCarPrint() {
        superCar.print();   // superCar print
    }

    public void goodCarPrint() {
        goodCar.print();    // goodCar print
    }
}    

공통점

모두 Java에서 제공하고 있습니다.

@Resource

import javax.annotation.Resource;

 

@Qualifier

번외로 @Qualifier를 사용하면 좀 더 유연하게 의존관계를 맺을 수 있습니다.

동일한 Type의 Bean이 2개를 컨테이너에 등록했다고 가정해봅니다. @Autowired 를 사용하여 해당하는 Type을 선언하여 의존관계를 맺으려 합니다. 하지만 @Autowired에서 2개 중 어떤 Bean을 가져와야할지 몰라 동일한 Bean이 2개 존다한다는 Exception을 발생시킵니다.

@Configuration
public class CarConfiguration {

    @Bean(value = "car1")
    public Car superCar() {
        return new SuperCar();
    }

    @Bean(value = "car2")
    public Car goodCar() {
        return new GoodCar();
    }

}
@Component
public class LoadMap {

    @Autowired
    private Car goodCar1;    // Exception 발생
}

 

이런 경우 @Qualifier를 사용합니다.

동일한 Type의 Bean을 선언하지만 @Qualifier를 사용하여 한정자를 설정합니다. 위 코드에서 @Qualifier를 적용하여 수정해보도록 하겠습니다.

@Configuration
public class CarConfiguration {

    @Bean(value = "car1")
    @Qualifier(value = "car1")	// SuperCar Bean을 car1로 등록
    public Car superCar() {
        return new SuperCar();
    }

    @Bean(value = "car2")
    @Qualifier(value = "car2")
    public Car goodCar() {
        return new GoodCar();
    }

}
@Component
public class LoadMap {

    @Autowired
    @Qualifier("car1")
    private Car goodCar;    // SuperCar DI

    public void superCarPrint() {
        goodCar.print();    // SuperCar print
    }
}    
반응형