Spring/DI & AOP

학습 // Spring // DI // 의존성주입( Injection )

문스코딩 2018. 8. 7. 16:32
업데이트 :: 2018.08.07



의존성주입을 사용하는 이유?

  • 객체를 실제 코드흐름에 생성하는 것이 아닌 외부에 생성된 객체를 가져와 사용하는 방식
  • 클래스간의 결합도를 낮춰 재사용성을 높임

의존성주입 종류

  • 설정자 기반 의존성 주입 방식
  • 생성자 기반 의존성 주입 방식
  • 필드 기반 의존성 주입 방식

설정자 기반 ( Setter Injection )

public class UserServiceImpl implements UserService {
  private UserRepository userRepository;
  private PasswordEncoder passwordEncoder;

  public UserServiceImpl() {

  }

  public void setUserRepository(UserRepository userRepository) {
    this.userRepository = userRepository;
  }

  public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
    this.passwordEncoder = passwordEncoder;
  }
}

java기반(bean이용)

@Bean
UserService userService() {
  UserServiceImpl userService = new UserRepositoryImpl();
  userService.setUserRepository(userRepository());
  userService.setPasswordEncoder(passwordEncoder());
}

java기반(매개변수)

@Bean
UserService userService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
  UserServiceImpl userService = new UserRepositoryImpl();
  userService.setUserRepository(userRepository);
  userService.setPasswordEncoder(passwordEncoder);
}

xml기반

<bean id="userService" class="com.example.demo.UserService">
  <property name="userRepository" ref="userRepository" />
  <property name="passwordEncoder" ref="passwordEncoder" />
</bean>

Annotation기반 ( 자동으로 주입 )

@Component
public class UserServiceImpl implements UserService {
  private UserRepository userRepository;
  private PasswordEncoder passwordEncoder;

  @Autowired
  public void setUserRepository(UserRepository userRepository) {
    this.userRepository = userRepository;
  }

  @Autowired
  public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
    this.passwordEncoder = passwordEncoder;
  }
}
  • @Autowired를 달아주면 java기반의 설정방식이나 xml기반의 설정방식이 필요 없음

생성자 기반 ( Constructor Injection )

xml 기반 ( 인덱스사용 )

<bean id="userService" class="com.example.demo.UserServiceImpl">
  <constructor-arg index="0" ref="userRepository" />
  <constructor-arg index="1" ref="passwordEncoder" />
</bean>

xml 기반 ( 인수명사용 )

<bean id="userService" class="com.example.demo.UserServiceImpl">
  <constructor-arg name="userRepository" ref="userRepository" />
  <constructor-arg name="passwordEncoder" ref="passwordEncoder" />
</bean>
  • 인수명은 매개변수의 순서가 바뀌어도 괜찮다는 장점
  • 인수명 정보는 소스코드가 컴파일 되는 과정에서 사라짐
    • @ConstuctorProperties Annotation을 사용하면 인자값을 컴파일 후에도 유지

@ConstructorProperties({"userRepository", "passwordEncoder"})
public UserServiceImpl(UserRepository userRepository, PasswordEncoder passwordEncoder) {
  // do something...
}
  • 컨스트럭트 인젝션만이 필드를 final로 선언해서 생성후에 변경되지 않게 만들 수 있음

필드 기반 ( Field Injection )

@Component
public class UserServiceImpl implements UserService {
  @Autowired
  UserRepository userRepository;

  @Autowired
  PasswordEncoder passwordEncoder;
}
  • DI 컨테이너의 힘을 빌려 의존성을 주입하는 방식
  • DI 컨테이너의 사용을 전제해야 한다는 것

Created by MoonsCoding

e-mail :: jm921106@gmail.com

반응형