티스토리 뷰

반응형

Dependency Injection (의존성 주입) 

"스프링 철저 입문" 책 정리

 

배경 

의존관계를 가지는 컴포넌트들의 결합도를 낮추기 위해 나타남

 

- 컴포넌트 내에서 직접 의존관계를 가지는 컴포넌트에 대한 인스턴스 생성

public class UserServiceImp implements UserService{

	private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

	public UserServiceImp(){
    	
        //구현체를 직접 생성
    	this.userRepsitory = new UserImplRepository();
        this.passwordEncoder = new BCryptPasswordEncoder();
    }
    
    ....
}

 

userRepository, passwordEncoder에 대한 구현체가 바뀐다면?

=> UserserviceImp 클래스를 직접 수정해야 함.

 

- 외부에서 UserService가 필요한 컴포넌트를 생성하고 UserService의 인스턴스 생성 시 주입

...

UserRepository userRepository = new UserImplRepository();
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

UserService userService = new UserServiceImp(userRepositry, passwordEncoder);

...

 UserService 내부 코드는 UserRepository, PasswordEncoder의 구현체가 변경되더라도 영향을 받지 않는다.

 

하지만, 여전히 개발자가 직접 구현체를 생성해서 주입해야 하는 번거로움이 남아있다.

 

DI 컨테이너는 이러한 번거로운 과정을 대신 처리한다. 

- 인터페이스, 구현체, 의존관계를 정의해주면,

컴포넌트를 생성할 때, 자동으로 의존관계를 가지는 컴포넌트를 생성하여 주입한다.

 

* DI 컨테이너가 컴포넌트를 꺼내오는 방법 

ApplicationContext context = ...;   //스프링 DI 컨테이너
UserService userService = context.getBean(UserService.class);

 

 

장점

- 인스턴스의 스코프를 제어할 수 있음

( 싱글톤 또는, 프로토타입으로 컴포넌트 호출 가능 )

- 인스턴스의 생명 주기를 제어할 수 있음

- AOP 방식으로 공통 기능을  집어넣을 수 있음

- 의존하는 컴포넌트 간의 결합돌르 낮춰서 단위 테스트하기 쉽게 만듦 

 

 

 


 

ApplicationContext 

스프링에서의 DI Container 

 

 

스프링의 DI Container에 컴포넌트 등록하는 방법

1. @Configuration + @Bean : 자바 기반 컴포넌트 등록 방식

2. XML 기반 컴포넌트 등록 방식 

3. ComponentScan : 어노테이션 기반 컴포넌트 등록 방식 

 

※ 룩업(lookup) : DI Container 에서 빈을 찾아오는 행위

※ 빈(Bean) : DI Container에 등록된 컴포넌트 (스프링 환경에서) 

※ 빈 정의(Bean Definition) : 빈에 대한 설정 저보 (Configuration)

 

 

1. 자바 기반 설정 방식

: 자바 코드로 빈 설정 

: 이 때 사용되는 자바 코드 -> Configuration 클래스

: 컴포넌트의 빈 설정에 필요한 모든 컴포넌트 또한 빈으로 설정해야 함 (설정해야 할게 많음...)

-> 어노테이션 설정 방식과 함께 사용하여, 많은 부분을 줄일 수 있음

@Configuration
public clas AppConfig{

	@Bean
	public UserRepository userRepository(){
    	return new UserImplRepository();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder(){
    	return new BCryptPasswordEncoder();
    }
    
    /////////////////////////
    
    @Bean // ---- (1) 메서드 내에서 의존성 주입
    public UserService userService(){
    	return new UserServiceImpl(userRepository(), passwordEncoder());
    }
    
    @Bean // ---- (2) 메서드의 매개변수를 통한 의존성 주입
    public UserService userService(UserRepository userRepository, PasswordEncoder passwordEncoder){
    	return new UserServiceImpl(userRepository, passwordEncoder);
    }
    
}

 

 

2. XML 기반 설정 방식

: <beans> 내 <bean> 태그에서 속성  id(bean 명), class(구현클래스-FQCN) 를 이용하여 bean을 등록한다.

:  <constructor-arg> 태그에서 ref 속성을 이용해 의존성 주입할 빈 이름을 기재한다, value 속성을 이용하여 특정 값 또한 기재할 수 있다. 

※ FQCN : Fully Qualified Class Name - 패키지 명을 포함한 클래스 명

 

 

3. 어노테이션 기반 설정 방식

: 빈 정의 어노테이션을 클래스에 부여

: ComponentScan을 통해, @Component가 붙은 클래스를 DI Containter에 자동으로 등록

: 어노테이션이 붙은 클래스에 대해서 DI Container가 자동으로 의존성 주입 수행 => 오토 와이어링(Auto Wiring)

@Component
public class UserImplRepository implements UserRepository{
	...
}

@Component
public class BCryptPasswordEncoder implements PasswordEncoder{
	...
}

////////////////

@Component
public class UserServiceImpl implements UserService{
	
    @Autowired   // ----------- DI Container가 자동으로 주입해줌
    UserRepository userRepository;
    
    @Autowired   // ----------- DI Container가 자동으로 주입해줌
    PasswordEncoder passwordEncoder;
}

 

 

* 자바 + 어노테이션 기반 설정 방식

: Configuration 클래스에 ComponentScan을 붙여서 사용

@ComponentScan("com.example.base")   //---- DI Container에 자동으로 등록할 컴포넌트를 찾는 패키지 경로 설정
@Configuration
public class AppConfig{

	...

}

 

 

* Bean 명

: Bean 명은 기본적으로 클래스 명의 첫 글자를 소문자로 바꾼 이름과 같다. 

: 첫글자부터 대문자가 연속으로 2회이상 나오면 그대로 클래스 명 그대로 이름이 등록된다. 

ex)

UserService -> userService

BCryptPasswordEncoder -> BCryptPasswordEncoder 

 

: 이름 변경을 원할 경우, 어노테이션에 명시적으로 이름을 작성한다.

ex)

@Component("userService")

 

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함