타인이 되지 말고 자신이 되어봐요

Be yourself, not others

Programming/Spring(Spring Boot)

[TIL] Spring Boot - 자바 코드로 직접 스프링 빈 제공하기, 의존성 주입

kcdevdes 2023. 6. 20. 18:39

출처 및 자료

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/

 

[무료] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 - 인프런 | 강의

스프링 입문자가 예제를 만들어가면서 스프링 웹 애플리케이션 개발 전반을 빠르게 학습할 수 있습니다., - 강의 소개 | 인프런

www.inflearn.com

스프링 빈을 직접 제공해보자!

저번 포스팅에서는 스프링 빈이 무엇이고 왜 쓰여야 하는 지, 그리고 특징은 어떤 게 있는 지 작성했었다.

@Component(Service, Controller, Repository) 어노테이션이 붙은 클래스들을 빈으로 스프링이 자동으로 등록한 후 @Autowired를 입력한 곳에 적재적소에 넣어주는 것까지 알아보았다. 그러면 만약, 내가 직접 스프링 빈을 넣고 싶을 땐 어떻게 해야할 까?? 다음과 같이 등록할 수 있게 된다.

 

@Configuration
public class SpringConfig {

	// Bean을 요청받을 때마다 새로운 MemberService 객체를 돌려준다
    @Bean
    public MemberService memberService(){
        return new MemberService(memberRepository());
    }
    
    @Bean
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }
}

 

이렇게 작성하는 경우, 이후에 MemberService란 객체 (멤버를 등록, 수정, 제거, 검색하는 서비스)를 사용하는 모든 곳에 일괄 적으로 수정사항을 등록할 수 있게 된다. 예를 들어, MemberService가 사용하는 Repository가 변경되는 경우 - DB저장소의 변경 등등..- 같이 일괄적으로 모든 곳의 의존성을 변경할 필요가 있을 때 쓰일 수 있다.

 

의존성 주입하는 방법들

의존성은 다양한 방법으로 주입할 수 있는데, @Autowired된 생성자도 그 중 하나이다. 다른 것으로는 다음 것들이 있는데...

 

1. 필드 주입

필드는 클래스에 있는 고유의 변수를 뜻한다. 이 곳에 @Autowired로 직접 주입하는 것도 가능은 한데, 아마 Intellij IDEA 처럼 IDE를 사용하면 '사용을 권하지 않음'경고가 출력될 것이다. 그 이유는 필드 주입된 객체는 외부 접근 불가와 함께 객체 변경이 원천 불가하기 때문에, 외부 사용되는 필드나 테스트 코드에서 부적절하기 때문이다.

 

class ExampleComponent {
    @Autowired
    private final MyRepository myRepository;
    
    ...
 }

2. Setter 주입

Setter로도 주입이 가능하다. Setter 주입은 일반적인 자바 코드 스펙 (생성자, Getter/Setter, toString(), equals())와 같이 사용할 수 있다는 장점이 있지만, Setter 특성 상 public으로 사용되는 것 + 여러 번 초기화 가능하다는 문제로 인해 실수로 인한 의존성 수정을 막을 방법이 없다는 것에서 주의해야한다. (물론 코드로 짜면야 막을 수 있겠지만 그럴 바엔 생성자 주입이 더 편하지 않을까 생각해본다 ㅎㅎ...)

class ExampleComponent {
    private MyRepository myRepository;

	...	
    @Autowired
    public void setMyRepository(MyRepository myRepository) {
        this.myRepository = myRepository;
    }
    
    ...
}

 

3. 생성자 주입

생성자로 주입하는 것 또한 가능하다. 생성자로 주입되기 때문에 1회 초기화가 보장됨과 동시에 이후 수정을 원천 차단, 해당 컴포넌트를 생성할 때 주입을 강제할 수 있게 되어 Spring에서 가장 적극적으로 활용된다 (심지어 생성자에 @Autowired를 생략해도 무관)

class ExampleComponent {
    private final MyComponent myComponent;

    @Autowired
    public ExampleComponent (MyComponent myComponent) {
        this.myComponent = myComponent;
    }

}

끝!