DI 와 IOC 그리고 AOP

hyuko·2022년 10월 29일
0

Spring-Study

목록 보기
3/8

1. 앞서 java를 배우면서....

객체 지향 프로그램 OOP적 개념과 인터페이스를 사용해 왔습니다.

이번에 배울 Spring에서의 DI 그리고 IOC의 개념은 OOP와는 
사뭇 다른 느낌의 프로그램인데요!

MVC기반을 두고 OCP의 개념 (개방과 폐쇄)의 전략 패턴을 사용합니다.

스프링에서는 DI적 개념이 필수이고, 가장 다른 언어들과 
차이점이라고 할 수 있는데, 처음에는 그런 생각을 해봤습니다.

DI에 결국 인터페이스를 쓰는 것이고 그럼 DI를 만들 때 마다
인터페이스를 하나씩 만들어서 써야하는 걸까?

일단. DI의 구조를 알아본다면!
Controller가 있고 그 Controller는 인터페이스와 연결되어
바라보고 있는 상황이고, Service의 중심이 되는
인터페이스와 연결되어 있는 Service 클래스가 있다면

Controller는 코드상 인터페이스만 바라보고 있는 상황이라
코드가 실행되어 런타임 시점까지 구현체가 만들어지지 않는다.

결국 컨트롤러 입장에서는 인터페이스에 있는 메소드를
이용해서 로직을 구성하기 때문에 서비스 클래스 내부 로직이
어떻게 변화하던 영향을 받지 않는 구조입니다.
그렇기에 변화에는 닫혀있는 구조가 된다.

반대로 서비스 클래스는 인터페이스에서 규정된 규칙만 잘 지키면
언제든 변화할 수 있는 클래스가 됩니다.(확장은 열려있다)

2. 여기서 드는 의문점!!!

굳이 클래스들을 그냥 수정하면 그 클래스들만 수정해서 로직이 바뀌게되면
디버깅등 테스트를 거친뒤에 바꿔주면 되는데 인터페이스를 하나씩
만들면서 까지 해주어야 하나 싶은데!

객체지향적 전략적 이런 패턴들은 최대한 각각의 코드의 결합력을
낮춰주는데 특화된 디자인 패턴들이기 때문에 각각 분리시켜 사용한다!

그래서 자바의 인터페이스 사용은 객체지향프로그램의 가장 기본 구조가 된다.

3. 여기서 알아야할 점!

그냥 아무대나 인터페이스를 쓰고 DI를 사용하고 하는 것이 아니라
추후에도 변경될 일이 거의 없고 하나의 정보가 바뀔때
다른 한쪽도 무조건 바뀌어야 하는 상황의 클래스라면!!
굳이 인터페이스나 DI를 사용하지 않아도 되는 것 이다.

4. 결국 프로그래밍을 한 후에 확장을 계속하고 변동이 있는 프로그램들을 다룰 때 이용하는 것이다.!!!

DI의 실행 방법에는 두가지가 있습니다.
XML로 표현하는 방법과 @ 어노테이션으로 사용하는방법

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
  <context:component-scan base-package="com.spring.di"></context:somponent-scan>
  <bean id="centralControl" class="com.spring.di.CentralController2">
		
	</bean>
</beans>

위의 방법은 JSP에서 쓰는 것 처럼 XML형식으로 쓰는 방법입니다.

어노테이션으로 사용하는 방법에는

  • @Autowired
    • 기본값은 required = true입니다. 값이 null 이 될 수 없다는 뜻
      이 어노테이션을 쓰게 되면 인터페이스의 모든 클래스들을 자동으로 주입!!!
      하겠다는 것이고 이 어노테이션 밑의 임퐅트가 되는 곳에 클래스를 자동 주입
      해서 쓰는 것입니다!
      하지만! 여기서 null값을 넣어야 할 때 넣고 싶을 때 쓰는것은
      @Autowired(required = false)라고 적어주면된다.

  • @Qualifier("객체")
    • 오토 와이어드를 실행 하는데 받아올 객체가 여러개라면
      오토와이어드가 제대로 실행하지 않게 됩니다.
      그 때 퀄리파이어를 이용해서 들고올 객체를 지정해줍니다

  • @Value("값")
    • 기본 값을 지정해준다.
      class 위에 @Component를 붙인 후("값")을 지정해주면
      클래스가 생성 될 때 그 값으로 들어가게 된다.

위와같은 어노테이션들을 실행 하기 위해 필요한 xml문구가 있습니다
context:annotation-config -> 객체를 생성할 때에 클래스를 실행할 때
어노테이션이 있다면! 먼저 실행을 하라 라는 의미의 문구입니다.

하지만 Component 라는 어노테이션은 위의 문구가 적용되지 않습니다.
그래서 여기서 쓰는 값은
<context:component-scan base-package="">
base package안은 어디에 읽어올 파일이 있는지
경로를 입력해주고 이 문구를 쓰게되면
위의 어노테이션 콤피그는 쓰지않아도 정상 작동됩니다.

@Controller : page 처리를 할 때

@Service: 로직 처리

@Repasitory : 디비 정보를 받아서 service에게 넘겨주는 역활

@Configuration: 웹에 있는 설정들을 등록 할 때 사용합니다.

5. IOC (Inversion Of Control)

IOC란 무엇일까?

  • 제어의 역전 :

    AppConfig의 등장 전

    • 즉 기존에는 클라이언트의 구현객체가 스스로 필요한
      서버 구현 객체를 생성하고, 연결하고, 실행을 했다.
    • 이 말 즉슨 구현 객체가 프로그램의 제어흐름을 스스로 조종했다고
      생각하면 된다.

    AppConfig의 등장 후

    • 구현 객체는 자신의 실행 로직만을 담당하게 되고(책임에 대해 더욱 더 견고 해진다.)
    • 제어의 흐름은 모두 AppConfig에서 하게된다.

    예를 들어 주문을 하는 서비스가 있다고 한다.
    이 서비스에 필요한 인터페이스들은 호출을 하게 되지만
    어떤 구현체(객체)가 실행되는지는 알 수 없다.

    이 말 즉슨 주문 서비스 즉 주문하는 행동은
    실행이 되지만 어떠한 상품이 주문이 되는지 ,
    어떤 고객이 주문을 하는지 , 얼마나 discount되는지
    등등 이러한 것들에는 신경을 쓰지 않게된다.

    각각의 행동들에는 책임을 지게 되지만 객체의 (변경)은 되지않는다.

    정리

    이 와 같이 프로그램의 제어흐름을 직접 제어 하는 것이 아닌
    외부에서 관리하는 것을 제어의 역전 IOC라고 한다.

    IOC 컨테이너에서 작동한다고 DI를 쓰는 것은 아니다.
    DI의 개념은 어떠한 인터페이스의 작동이 구현체가 생성이 될 때
    그 생성되는 구현체의 객체에 외부로부터 주입이 되는 개념이다.

profile
백엔드 개발자 준비중

0개의 댓글