개발 하나둘셋/Java & Spring

스프링 DI ,IOC, AOP

유리코딩 2022. 4. 11. 21:15
반응형

개념정리

스프링 DI ,IOC, AOP

 

 

스프링의 가장 큰 특징인 제어의 역전(IOC), 의존성 주입(DI), 관점 지향 프로그래밍(AOP). 전에 블로그에 포스팅을 했음에도 면접질문으로 나왔을 때 제대로 대답을 못했던 기억이 있다😥  그래서 다시 한번 정리!

 

 

IoC(Inversion of Control, 제어의 역전IoC)

1. 개념

  • Spring 에서는 Container라는 개념이 있는데, 이 컨테이너는 객체를 담는 용기
  • 스프링컨테이너가 필요에 따라 개발자 대신에 bean의 생성부터 소멸까지 생명주기를 관리
  • 객체의 의존성을 역전시켜 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 하여 가독성 및 코드 중복, 유지 보수를 편하게 할 수 있게 함

 

2. 컨테이너(Container)

  • 스프링의 컨테이너는 프로그래머가 작성한 코드의 처리과정을 위임받아 독립적으로 처리하는 존재
  • 객체관리를 주로 수행하는 그릇
  • 필요성 : 의존성 제어, 즉 객체 간의 의존성을 낮추기 위해 바로 Spring 컨테이너가 사용됨
    • 객체를 사용하기 위해서 new 생성자를 이용하거나 getter/setter 기능을 주로사용하는데 많이 사용할 수록 의존성이 높아짐. 낮은 결합도와 높은 캡슐화를 중시하는 OOP에서 높은 의존성은 좋지 않음.

 

 

DI(Dependency Injection, 의존성 주입)

1. 개념

  • 객체 사이에 필요한 의존 관계에 대해서 스프링 컨테이너가 자동으로 연결해 주는 것
  • 스프링 컨테이너는 DI를 이용하여 빈(Bean) 객체를 관리하며, 스프링 컨테이너에 클래스를 등록하면 스프링이 클래스의 인스턴스를 관리

 

2. DI가 필요한 이유(DI의 장점)

  • 클래스를 재사용 할 가능성을 높이고, 다른 클래스와 독립적으로 클래스를 테스트 할 수 있다.
  • 비즈니스 로직의 특정 구현이 아닌 클래스를 생성하는데 매우 효과적
  • DI(의존성 주입)를 통해서 모듈 간의 결합도가 낮아지고 유연성이 높아진다.

 

3. DI의 세가지 방법

  • Contructor Injection : 생성자 삽입
  • Method(Setter) Injection : 메소드 매개 변수 삽입
  • Field Injection : 멤버 변수 삽입


4. IoC / DI 예제

<SoccerBall>

interface SoccerBall {
  String touchBall();
}

@Component("adidasBall") // adidasBall이란 이름을 가진 Bean으로 등록
public class AdidasSoccerBall implements SoccerBall {
  public String touchBall() {
      return "아디다스 축구공이 굴러간다!";
  }
}

@Component("nikeBall") // nikeBall이란 이름을 가진 Bean으로 등록
public class NikeSoccerBall implements SoccerBall {
  public String touchBall() {
      return "나이키 축구공이 굴러간다!";
  }
}

<SoccerPlayer>

@Component // 의존성을 주입받는 객체도 Bean으로 등록되어야 한다.
public class SoccerPlayer {
    @Autowired
    @Qualifier("nikeBall")
    private SoccerBall ball;

    public String playSoccer() {
        return "축구선수가 공을 찼다! \n" + this.ball.touchBall();
    }
}

<SoccerController>

@RestController
public class SoccerController {
    @Autowired // SoccerPlayer라는 타입을 가진 Bean을 찾아서 주입시킴
    private SoccerPlayer soccerPlayer;

    @RequestMapping("/soccer")
    public String soccerDriver() {
        return soccerPlayer.playSoccer();
    }
}
  •  @Component라는 어노테이션이 붙은 클래스들은 Spring의 Container가 알아서 Spring Bean 객체로 등록하고 생성
  • 이렇게 생성된 객체는 @Autowired라는 어노테이션이 붙은 변수의 타입(타입이 같은 Bean 여러개 있다면 이름을 본다.)을 보고 해당 변수에 객체를 주입
  • 스프링의 Container가 대신 객체를 생성해주고 알아서 객체를 주입함. 생성된 객체는 자신이 어디에 쓰일지 알지 못함
  • 이것이 제어 역전의 원칙 이며 스프링은 DI(의존성 주입) 라는 개념으로 구현

 

AOP(Aspect Oriented Programming, 관점 지향 프로그래밍)

  • 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화하겠다는 것
  • 모듈화란 어떤 공통된 로직이나 기능을 하나의 단위로 묶는 것을 말함
  • AOP에서 각 관점을 기준으로 로직을 모듈화한다는 것은 코드들을 부분적으로 나누어서 모듈화하겠다는 의미
  • 이때, 소스 코드상에서 다른 부분에 계속 반복해서 쓰는 코드들을 발견할 수 있는 데 이것을 흩어진 관심사 (Crosscutting Concerns)라 부름

 

위와 같이 흩어진 관심사를 Aspect로 모듈화하고 핵심적인 비즈니스 로직에서 분리하여 재사용하겠다는 것이 AOP의 취지

 

 

 

 

 

참고 

https://thenicesj.tistory.com/144

https://sehun-kim.github.io/sehun/springbean-lifecycle/

https://engkimbs.tistory.com/746

https://velog.io/@tjylo3437/Spring-Framework-IoCDIAOP

반응형