[Spring] Spring MVC

DI, DL 는 다르다.

IOC = DI 이제껏 같은 의미로 쓰고 있었다.

Inversion of Control (제어의 역전) 컨트롤 하는 방식이 거꾸로 되어버렸다.

Dependency Injection(의존성 주입)

A라는 객체가 작업시 B가 필요한 경우가 있따. 전통적 방식에서 A라는 클래스 안에서 B 생성

IOC는 DI와 DL 방식이 있다.

DI는 집어 넣어줬다면 DL은 필요한게 어딨는지 찾음.

오른쪽에 (컨테이너) 다야한 애들이 만들어져 있는데 필요한 객체들을 컨테이너 같은 데 가서 자기가 찾는거. 그럴떄 이름이 필요하다.

커넥션 풀이 그

기본형이면 value 아니면 어노테이션으로 주입하는 것도 있었다.


AOP

OOP와 AOP를 같이 쓸 수 있다.

20210428_093735

AOP는 관점 중심으로 코드를 짠다. Aspect를 관점으로 해석

AOP는 전체 어플리케이션 구현 기능을 2가지로 구분

  • 핵심업무(Core Concer)
    biz Logic
  • 공통업무 (Cross-cutting Concern)
    핵심업무를 도와주는 반복적이고 부가적인 업무.

20210428_102723

핵심 기능과 부가기능을 따로 분리해서 생각하고 설계해야 하낟.

20210428_103015

모듈 ABC가 아까 말한 핵심기능(이체,승인,계산)

저 중 진하게 색칠 된 부분이 공통부분.

20210428_103218

위 그림이

20210428_103320

이처럼 바뀐다 생각하면 된다.

위빙?

Advice를 핵심 로직 코드에 적용하는 것을 weaving 이라고 한다.(분리한 관점을 여러 차례 모률에 삽입하는 것을 AOP에서는 위빙 (Weaving: 엮기)이라고 부른다.) 즉 공통 코드를 핵심 로직 코드에 삽입하는 것이 weaving이다.

어드바이스를 핵심 로직 코드에 삽입하는 것을 위빙이라고 한다.

Aspect를 target 객체에 제공하여 새로운 프록시 객체를 생성하는 과정을 말한다.

스프링 AOP에서의 용어

  • JoinPoint - 클래스의 인스턴스 생성시점, 메서드 호출시점 및 예외발생 시점과 같이 어플리케이션을 실행시 특정 작업이 시작되는 시점.

  • Advice - JoinPoint에 삽입되어져 동작할 수 있는 코드

  • PointCut - 여러개의 조인포인트를 하나로 결합(묶은) 것.

묶은 이유? - 적용시켜야 하는 공통 기능이 같은거.

20210428_104131

조인포인트 = ~ 할떄

  • Weaving - 어드바이스를 핵심 로직 코드에 삽입하는 것

  • target - 핵심 로직을 구현하는 클래스

  • aspect - 여러 객체에 공통으로 적용되는 관점사항.

핵심업무 중간에 끼어들어가서(위빙) 막 로그 남기고 가거나 권한체크 하거나 그런식

작업하는 내용을 가지고 있는 메서드. 그 어드바이스를 가진 애가 aspect라는 애.

20210428_104754

20210428_105315

20210428_105326

어드바이스 - 끼어들어가는거 포인트 아웃은 - 언제

언제 끼어들어가서 뭐할건데?

읽기 할떄 뭐 하럭ㄴ데 쓰기 할떄 뭐할껀데

이런식으로 떄를 모아둔 거.


SPRING AOP 특징

  • proxy 기반의 AOP는
    target 객체에 대한 프록시를 만들어 제공
  • proxy
    타겟을 감싸는 구조로 런타임에 생성

: Advice 를 타겟 객체에 적용

프록시가 먼저 요청 받고 판단함. 클라이언트가 go라는 메서드 들어왔는데 공통 어드바이스 끼워넣을게 있나? 체크함.

20210428_112038

20210428_112223 20210428_112748

20210428_112801

지정어가 와야 타입 알 수 있다.

  • (*) 는 뭐가 와도 되고 만약 *service면 뒤가 서비스가 와야.

포인트 컷의 예제

20210428_113612

20210428_113612

맨 처음 플젝 생성하면 pom.xml 을 보자.

프로젝트 만들면 메이븐이라는 툴이 관리해주는데 이 기능여러가지 중 대표적으로 체감할 수 있는게 라이브러리를 자동으로 관리해준다.

필요한 라이브러리가 있으면 pom.xml에 말하면 알아서 넣어줌.

디펜던시가 라이브러리라 생각하면 된다.

20210428_114010

groupid, artifactid, 네임 이런거 다 다운받아야.


Spring MVC

  • 스프링이 제공하는 서블릿 기반의 MVC프레임워크이다.

  • 프론트 컨트롤러의 역할을 하는 DispatcherServlet을 사용한다.

  • 스프링이 제공하는 AOP, 트랜잭션 처리 , DI 등의 기능을 그대로 사용하면서 MVC 패턴에 기반하여 웹 어플리케이션을 개발할 수 있다.

20210428_142220

  1. 클라이언트가 요청 보냄(url 주소창에 보냄) DispatcherServlet이 제일 먼저 받음 클라이언트의 모든 요청을 받는 서블릿임.(frontcontroller와 같은 역할)

  2. 요청 url과 매핑되는 컨트롤러 검색 Handler매핑이 들어온 요청을 처리할 컨트롤러를 결정해줌.

  3. 다시 누가 일해야 되는지 디스패쳐 서블릿에 알려줌,

  4. 컨트롤러가 직접 작업 안하고 모델에 일을 시킴

  5. 모델 & 뷰를 디스패쳐 서블릿한테 리턴해줌.

  6. 데이터랑 뷰 전해줌. 이 데이터를 디비에서 꺼내왔으니 어디에 뿌려달라고 전해줌. 뷰 정보를 주긴 주는데 논리적인 화면정보임. (논리적인건 쉽게 생각하면, 이 데이터를 초기화면에 뿌려주세요 이런식. 물리적이 아님. 파일명이나 경로가 결정되지 않음.)

  7. viewResolver는 마지막 끝내는 애(내 손에서 끝내주겟다는 으미)

  8. 최종적으로 뷰로가라(jsp)

20210428_142153

mvc에서는 컨테이너 2개 사용

root Spring Container 모든 서블릿과 기타 등장하는 자바파일들 에서 다 같이 공유해서 쓸 수 있는 컨테이너

루트 컨테이너는 모든 서블릿이 다 가져다 씀.

스프링 mvc 프로젝트에선 미리 만들어 놓고 필요할 떄 가져다 쓰는 컨테이너가 2종류가 있다.

20210428_152611

하나가 루트 스프링 컨테이너라 불리는 컨테이너 하나. 다른하나는 DispatcherServlet 컨테이너.

컨테이너가 2개인ㄷ 디스패쳐 서블릿컨테이너는 디스패쳐 서블릿만 가져다 씀.

디스패쳐 서블릿 혼자 쓸수있는 컨테이너에 만들어지는거고

루트 컨테이너에 만들면 아무나 가져다 쓰기 가능.


20210428_172816

Filter - 전처리기, 후처리기

클라이언트와 서블릿 사이에 껴서 동작 헬로서블릿에서 응답 다하고 필터 또 거쳐서 최종 응답 나감.

필터는 실제 클라이언트가 호출한 대상 앞에서 전,후처리를 하는 것.


보충

20210428_184703

mybatis 가 저 Spring Orm 부분

  1. 스프링 코어 부분- > Container 기능

자식 클래스와 부모클래스 크기는 부모가 훨씬 큰 개념. (타입이)

Coffee cof = new CaffeLatte()에서 Coffee cof 여기가 더 큰 부분이므로 뒤에 생성되는 거만 바꾸면 됨.

Coffee cof = new Americano()

20210428_192029

xml생성시 xml파일이 아닌 Spring bean configuration file로 해야한다.(검은색으로 칠한 부분)

이제 자바는 안 고치고 xml만 고치면 된다.


IOC = DI (Dependency Injection)

Inversion of Controller 제어의 역전이라 부른다.

X가 컨테이너에 요청해서 (getbean) 달라고 요청. A가 있는데 A가 작업하려면 B가 또 필요함. C도 필요함. A안에다 B랑 C를 넣어줘야함. 이때를 주입이라고 함. 그럼 A는 들여다보면 B,C가 들어있는거. B,C가 있어야 메서드 호출할때 b.메서드 호출할수 있음. 작업할 때 다른애가 필요하면 A에서 만들지 않고 DI라는 애 이용.

컨테이너 내부에서 A가 작업하려면 B,C 다 미리 주입시켜놓고 다 주입이 된 A를 X는 컨테이너에 있는 A만 getbean한번만 하면 됨.

주입은 어떤 클래스가 작업하면서 다른 애가 필요한 거.

객체들이 막 여러개가 있는데 컨테이너 다른애가 필요 = 의존 컨테이너가 알았다고 넣어주는 거. A한테 B, C 이런게 들어갈 수 있다

주입은 2가지 방법이 있다.

  1. 생성자를 통해
  2. set 메서드를 통해(setter)

bean 쓰면 내부적으로 객체 하나 만들어지는데 그게 디폴트 생성자다.(파라미터 없는 생성자)


public class Americano implements Coffee{
	//사용전에 값이 주입이 되어있어야 함.
	int price;
	String origin;

	//1.생성자를 이용한 주입

	public Americano(int price) {
		this.price = price;
	}
	//2.setter를 이용한 주입.
	public void setOrigin(String origin) {
		this.origin = origin;
	}

	public void info() {
		System.out.println("Americano:강렬한 에스프레소 샷과 뜨거운 물의 조화");
		System.out.println("price"+price);
		System.out.println("origin"+origin);

	}
}

근데 이런식으로 파라미터로 주면 반드시 파라미터를 주면서 생성해야한다(디폴트 생성자를 더이상 사용 불가)

그래서

<constructor-arg name = "price" value ="5000"/>

이걸 써준다.

constructor-arg, property.

객체 참조시엔 ref(reference를 사용해준다.)

<bean id = "star" class = "com.coffee3.di.Starbucks">

	<constructor-arg name = "ame" ref = "coffee2">  </constructor-arg>

	<constructor-arg name = "ame" ref = "coffee1">  </constructor-arg>
</bean>

이렇게 객체인 경우에는 value가 아닌 ref로 해줘야 한다.





© 2021.03. by yacho

Powered by github