2023년 1월 1일
08:00 AM
Buffering ...

최근 글 👑

@AutoWired의 원리 , AutoWired란?

2023. 5. 2. 16:51ㆍ[자바]스프링

 

<AutoWired란>

1.AutoWired란 말 그대로 자동연결이란 뜻이다.

AutoWired는 필드에 있는 객체들을 자동으로 주입시켜주는 것이 AutoWired이다.

코드로 본다면

 

 

 

 

 

나는 ItemService라는 클래스에 ItemRepository라는 클래스를 필드에 선언했다.

다들 자바 기초는 알고 있겠지만 이 itemRepository라는 변수안에 값을 주입시키지 않는다면

이 변수는 null이 된다. 아무값도 안넣엇기 때문에 null이 될 수 밖에 없고 이걸 만약 사용하면

NullPointException이 발생하게 될것이다.

하지만 @AutoWired를 사용한다면 이 itemRepository라는 인스턴스 변수에 "자동으로" ItemRepository라는 클래스가 주입되게 된다.

 

마치 어떤형식이냐면

 

 

 

 

이렇게 new로 생성해서 ItemRepository가 주입된거와 같은 효과가 있다.

그렇다면 이 @AutoWired를 쓰는 이유가 뭘까? 단순히 코드가 간결해지는 효과도 있지만

싱글톤과 스프링컨테이너가 관리하는 장점이 있기 때문이다.

 

 

 

 

 

오토와이어드를 알기전에 스프링 컨테이너를 알아야 하는데

 

 

 

스프링 컨테이너가 이렇게 있으면 빈으로 등록된 객체를 스프링 컨테이너에서 관리한다.

그 안에서 등록된 객체가 있다면 @AutoWired로 자동주입이 가능하게 된다.

반대로 말한다면 스프링컨테이너에 등록된 객체가 없다면 @AutoWired를 정의 할 수 없게 된다.

스프링에 등록된 객체여야만 자동주입이 가능하게되고 등록하지 않는다면 스프링으로써는

이 클래스가 어떤 클래스인지 알 길이 없다.

 

대표적으로 등록하는 방법은 몇가지가 있는데

 

@Service

@Repository

@Compent

@Bean

 

이 4가지 어노테이션으로 등록을 많이 하게된다.

이 어노테이션들은 단순하게 클래스위에 붙인다면 자동으로 스프링 컨테이너에 등록되게 되며

Repository와 Service 어노테이션은 한개만 선언하는 편이 좋다.

그렇다면 다수의 객체를 스프링 컨테이너에 등록하기 위해선 어떻게 해야할까?

 

@Bean과 Compent를 사용하자.

 

@Compent를 사용한다면 자신이 스프링 컨테이너에 등록하고 싶은 객체에

컴포넌트를 붙여주면 된다.

 

@Bean을 사용하자.

 

@Bean은 수동등록이라고도 하는데 

 

 

코드로 본다면 이런느낌 일 것 이다.

이렇게 개발자가 수동으로 직접 주입시켜주는 코드를 작성 후 @Bean으로 등록하게 된다면

실행마다 스프링이 자동으로 Bean이 붙은 메서드나 클래스에 스프링 컨테이너에 등록하게 된다.

 

이렇게 @Bean을 사용하지 않고 개발자가 직접 자바코드로 스프링컨테이너에 넣는 방법도 있다.

그 방법은 여기를 참고하기 바란다.

 

 

AutoWired 사용 이유와 스프링 컨테이너의 사용 이유?

 

먼저, 객체를 생성하기 위해서는 new 생성자를 사용해야 한다. 그로 인해 애플리케이션에서는 수많은 객체가 존재하고 서로를 참조하게 된다.

객체 간의 참조가 많으면 많을수록 의존성이 높아지게 된다.

이는 낮은 결합도와 높은 캡슐화를 지향하는 객체지향 프로그래밍의 핵심과는 먼 방식이다.

따라서, 객체 간의 의존성을 낮추어(느슨한 결합) 결합도는 낮추고, 높은 캡슐화를 위해 스프링 컨테이너가 사용된다.

 

또한, 기존의 방식으로는 새로운 기능이 생기게 되면 변경 사항들을 수작업으로 수정해야 한다.

프로젝트가 커질수록 의존도는 높아질 것이고, 그에 따라 코드의 변경도 많아질 것이다.

하지만, 스프링 컨테이너를 사용하면 구현 클래스에 있는 의존성을 제거하고 인터페이스에만 의존하도록 설계할 수 있다.

 

그렇다면 AutoWired를 사용할때 주의 할 점은?

 

기본적으로 @AutoWired를 사용할때는 스프링 컨테이너의 있는 객체가 있을 경우에만 자동으로 등록 하게 해준다. 만약 우리가 Reposiotry나 Service객체를 직접만들어서 등록할 경우에는 @Service나

@Repository 어노테이션을 붙여 자동으로 등록할 수 있지만

자바에서 제공되는 클래스 중에서는 일부는 스프링컨테이너에 등록되어 있지 않기 때문에 Bean으로 수동으로 등록해줘야 하는 경우도 있다.

 

예를들어 querydsl에서 제공하는 JpaQueryFactory라는 클래스가 있다. 이 클래스는 dsl에서 제공하는 것이기 때문에 스프링컨테이너가 등록되어 있지 않기 때문에 Bean으로 등록하지 않는다면 사용 할 수 없다.

 

 

 

 

 

코드로 본다면

 

나는 자바에서 제공된 JpaQueryFactory를 사용하고자 한다.

하지만 JpaQueryFactory는 스프링 컨테이너에 등록되어 있지 않음으로 @AutoWired를 사용시에 찾을 수 없다고 뜰 것 이다.

 

이런식으로 오류가 뜬다.

즉 자바에서 제공하는 기본적인 클래스들은 스프링이 알아서 스프링컨테이너에 넣어주지만 

우리가 의존성으로 넣은 외부 라이브러리 같은 경우는 스프링 컨테이너에 없는 경우가 많기 때문에

외부 라이브러리를 가져다 사용할때는 반드시 Bean으로 수동으로 스프링 컨테이너의 등록 해줘야 한다.

 

 

요약하자면

 

AutoWired는 스프링 컨테이너에 등록되어 있는 객체에만 붙일 수 있으며 만약 스프링 컨테이너에 없는 객체를 AutoWired를 쓸려고하면 자동주입이 실패하게 되어 오류가 발생하게 된다.