hyuko

프레임워크? 스프링 프레임워크 본문

Springboot

프레임워크? 스프링 프레임워크

hyuko12 2023. 4. 25. 20:17
728x90
반응형

🔥 프레임 워크란?

뼈대나 근간을 이루는 코드들의 묶음이다.
개발자는 각 개개인의 능력차이가 큰 직업이고, 개발자의 구성에 따라
프로젝트 결과 역시 큰 차이를 낳는다.

이러한 상황에서 극복하기 위한 코드의 결과물이 바로 프레임 워크가 된 것이다.
프로그램의 기본 흐름이나 구조를 정하고 모든 팀원들이 이 구조에 
자신의 코드를 추가하는 방식으로 개발하게 된다.

프레임 워크의 장점

    개발에 필요한 구조를 이미 코드로 만들어 놓았기 때문에
    실력이 부족한 개발자라 하더라도 반쯤 완성한 상태에서
    필요한 부분을 조립하는 형태의 개발이 가능하다.
    
    회사의 입장에서는 프레임 워크를 사용하게 된다면 일정한 품질이
    보장되는 결과물을 얻을 수 있고, 개발자 입장에서는 완성된 구조에
    자신이 맡은 코드를 개발해서 넣기 때문에 개발 시간을 단축할 수 있다.
    
    

⭐ 스프링 프레임워크란?

    경량 프레임워크(Light-weight)
    예전 프레임 워크들은 다양한 경우를 처리할 수 있는 다양한 기능을 가지도록
    만들다 보니 하나의 기능을 위해서 너무 많은 구조가 필요했다.
    
    기술이 너무나 복잡하고 방대 했기 때문에, 전체를 이해하고 개발하기에는
    어려움이 많았다. 그래서 스프링 프레임워크가 등장을 했고, 특정 기능을 위주로
    간단한 JAR파일 등을 이용해서 모든 개발이 가능하도록 구성되어 있다.
    

스프링 프레임워크의 장점

    1. 복잡함에 반기를 들어서 만들어진 프레임워크이다.
    2. 프로젝트 전체 구조를 설계할 때 유용한 프레임워크
    3. 다른 프레임워크들의 포용(여러 프레임워크를 혼용해서 사용가능)
    4. 개발 생산성과 개발도구의 지원
    

스프링 프레임워크의 특징

- POJO (Plain Old Java Object) 기반의 구성

	오래된 방식의 간단한 자바 객체라는 의미이며, 
    JAVA 코드에서 일반적으로 객체를 구성하는 방식을 
    스프링 프레임워크에서 그대로 사용할 수 있다는 말이다.
		
- ⭐⭐ 의존성 주입(DI)을 통한 객체 간의 관계 구성

	의존성(Dependency)이란 하나의 객체가 다른 객체 없이
    제대로 된 역활을 할 수 없다는 것을 의미한다.
    예를 들어 A객체가 B객체 없이 동작이 불가능한 상황을 'A'가 'B'에
    의존적이다 라고 표현한다.
    
    ex) 레스토랑은 셰프없이 운영이 불가능하다 > 레스토랑이 셰프에 의존적이다.
    
    주입(Injection)은 말 그대로 외부에서 밀어 넣는 것을 의미한다.
    예를 들어 어떤 객체가 필요한 객체를 외부에서 밀어 넣는 것을 의미한다.
    주입을 받는 입장에서는 어떤 객체인지 신경 쓸 필요가 없고 
    어떤 객체에 의존하든 자신의 역활은 변하지 않게 된다.
    
    ex) 어떠한 환자가 병원을 찾아 병에대한 진단을 의사에게 받는다
    의사는 주사를 처방 한다. 
    주사에 어떠한 약물이 들었을 뿐 환자가 주사를 맞는 것에 어떠한 신경을 쓰지않는다.
    그렇다고 이 약물이 바뀐다하여 환자라는 사람이 의사가 되는 것은 아니다.
    
    ** 의존
    ⓐ →→→→→ ⓑ
    ( a라는 객체에서 b라는 객체를 직접 생성 )
    
    ** 의존성 주입
    ⓐ →→→ ??? ↔↔↔ ⓑ
    ( a는 b가 필요하다는 신호만 보내주고, b객체를 주입하는 것은 외부에서 이루어짐)
    
    ⭐ 의존성 주입방식을 사용하기 위해서는 ???라는 존재가 필요하게 된다.
    스프링 프레임워크에서는 ApplicationContext가 ???라는 존재이며,
    필요한 객체들을 생성하고, 필요한 객체들을 주입해주는 역활을 한다.
    
    따라서 개발자들은 기존의 프로그래밍과 달리 객체와 객체를 분리해서 생성하고,
    이러한 객체들을 엮는(Wiring)작업의 형태로 개발하게 된다.
    
    ApplicationContext가 관리하는 객체들을 '빈(Bean)'이라고 부르고,
    빈과 빈 사이의 의존 관계를 처리하는 방식으로는 XML방식, 어노테이션 설정,
    Java 설정 방식을 이용할 수 있다.

    
- AOP(Aspect-Oriented-programming) 지원
	
    관점 지향 프로그래밍,
    좋은 개발 환경에서는 개발자가 비지니스 로직에만 집중할 수 있게 한다.
    스프링 프레임워크는 반복적인 코드를 제거해줌으로써 핵심 비지니스 로직에만
    집중할 수 있는 방법을 제공한다.
    
    보안이나 로그, 트랜잭션, 예외처리와 같이 비지니스 로직은 아니지만, 
    반드시 처리가 필요한 부분을 횡단 관심사(cross-concern)이라고 한다.
    
    스프링 프레임워크는 이러한 횡단 관심사를 분리해서 제작하는 것이 가능하고
    횡단 관심사를 모듈로 분리하는 프로그래밍을 AOP라고 한다.
    
    이를 통해서 3가지의 이점이 생긴다.
    
    	1) 핵심 비지니스 로직에만 집중하여 코드 개발
        2) 각 프로젝트마다 다른 관심사 적용 시 코드 수정 최소화
        3) 원하는 관심사의 유지보수가 수월한 코드 구성 가능
        
- 편리한 MVC 구조

	[트랜잭션의 지원]
    	DB작업 시에 트랜잭션 관리를 매번 상황에 맞게 코드로 작성하지 않고, 
        어노테이션이나 XML로 트랜잭션 관리를 설정할 수 있다.
        
- WAS의 종속적이지 않은 개발 환경

	[단위 테스트]
    	전체 Application을 실행하지 않아도 기능별 단위 테스트가 용이하기 때문에
        버그를 줄이고 개발 시간을 단축할 수 있다.

 

SOLID 개념

SRP 단일 책임 원칙

Single responsibility principal

  • 한 클래스는 하나의 책임만 가져야한다
  • 하나의 책임이라는 것은 모호하다.
    • 클 수 있고, 작을 수 있다.
    • 문맥과 상황에 따라 다르다.
  • 중요한 기준은 변경이다. 변경이 있을 때 파급 효과가 작으면
    단일 책임 원칙을 잘 따른것!
  • 예) UI변경, 객체의 생성과 사용을 분리

OCP 개방- 폐쇄 원칙

Open/closed principle

  • 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야한다.
  • 이런 거짓말 같은 말이? 확장을 하려며ㅕㄴ, 당연히 기존 코드를 변경?
  • 다형성을 활용해본다.
  • 인터페이스를 구현한 새로운 클래스를 하나 만들어서 새로운 기능을 구현
  • 지금까지 배운 역할과 구현의 분리를 생각해본다.

문제점

  • 구현 객체를 변경하려면 클라이언트 코드를 변경해야 한다.
  • 분명 다형성을 사용했지만 OCP원칙을 지킬 수 없다.
  • 이 문제를 어떻게 해결해야 하나?
  • 객체를 생성하고, 연관관계를 맺어주는 별도의 조립, 설정자가 필요하다

LSP 리스코프 치환 원칙

Liskov substitution principle

  • 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야한다.
  • 다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야 한다는 것, 다형성을 지원하기 위한 원칙, 인터페이스를 구현한 구현체는 믿고 사용하려면, 이 원칙이 필요하다.
  • 단순히 컴파일에 성공하는 것을 넘어서는 이야기
  • 예) 자동차 인터페이스의 엑셀은 앞으로 가라는 기능, 뒤로 가게 구현하면 LSP 위반, 느리더라도 앞으로 가야한다.

ISP 인터페이스 분리 원칙

Interface segregation principle

  • 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다
  • 자동차 인터페이스 -> 운전 인터페이스, 정비 인터페이스로 분리
  • 사용자 클라이언트 -> 운전자 클라이언트, 정비사 클라이언트로 분리
  • 분리하면 정비 인터페이스 자체가 변해도 운전자 클라이언트에 영향을 주지 않음
  • 인터페이스가 명확해지고, 대체 가능성이 높아진다.

DIP 의존관계 역전 원칙

Dependency inversion principle

  • 프로그래머는 "추상황에 의존해야하지, 구체화에 의존하면 안된다." 의존성 주입은 이 원칙을 따르는 방법 중 하나다.
  • 쉽게 이야기해서 구현 클래스에 의존하지 말고, 인터페이스에 의존하라는 뜻
  • 앞에서 이야기한 역할(Role)에 의존하게 해야 한다는 것과 같다. 객체 세상도 클라이언트가 인터페이스에 의존해야 유연하게 구현체를 변경할 수 있다. 구현체에 의존하게 되면 변경이 아주 어려워 진다.

정리

  • 객체 지향의 핵심은 다형성!
  • 다형성 만으로는 쉽게 부품을 갈아 끼우듯이 개발할 수 없다.
  • 다형성 만으로는 구현 객체를 변경할 때 클라이언트 코드도 함께 변경된다.
  • 다형성 만으로는 OCP, DIP를 지킬 수 없다.
  • 뭔가 더 필요하다!!!!

 

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에서 하게된다.
    이 말 즉슨 주문 서비스 즉 주문하는 행동은
    실행이 되지만 어떠한 상품이 주문이 되는지 ,
    어떤 고객이 주문을 하는지 , 얼마나 discount되는지
    등등 이러한 것들에는 신경을 쓰지 않게된다.정리IOC 컨테이너에서 작동한다고 DI를 쓰는 것은 아니다.
    DI의 개념은 어떠한 인터페이스의 작동이 구현체가 생성이 될 때
    그 생성되는 구현체의 객체에 외부로부터 주입이 되는 개념이다.
  • 이 와 같이 프로그램의 제어흐름을 직접 제어 하는 것이 아닌
    외부에서 관리하는 것을 제어의 역전 IOC라고 한다.
  • 각각의 행동들에는 책임을 지게 되지만 객체의 (변경)은 되지않는다.
  • 예를 들어 주문을 하는 서비스가 있다고 한다.
    이 서비스에 필요한 인터페이스들은 호출을 하게 되지만
    어떤 구현체(객체)가 실행되는지는 알 수 없다.
  • AppConfig의 등장 전
    • 즉 기존에는 클라이언트의 구현객체가 스스로 필요한
      서버 구현 객체를 생성하고, 연결하고, 실행을 했다.
    • 이 말 즉슨 구현 객체가 프로그램의 제어흐름을 스스로 조종했다고
      생각하면 된다.
728x90
반응형

'Springboot' 카테고리의 다른 글

Netty  (0) 2024.07.19
spring security / 전체적인 흐름  (0) 2023.04.29
회원가입 / 로그인  (0) 2023.04.29
DB 테이블 설계 및 Entity  (0) 2023.04.28
스프링 부트 초기 설정 및 도서관리 어플리케이션 개발 시작  (0) 2023.04.28