스프링

스프링(Spring)

E재HO 2022. 10. 31. 00:04

스프링이 해주는 것들

 

POJO-쌩 자바객체를 칭하기 위한 별칭이다.

plain old java object :

특정 환경이나 기술에 종속적이지 않은 자바객체!

그냥 썡 자바에서 제공하는 것들을 사용할 수 있다는 뜻임

어떤 클래스나 인터페이스를 상속하지 않는 기본 자료형이나 String 객체 같은 것들을 사용함

테스트하기 용이(왜?자바만 있으면 돌릴 수 있으니까)+객체지향 설계를 자유롭게 적용이 가능

 

PSA(portable Service Abstraction)

환경 세부기술의 변경과 상관 없이 일관된 방식으로 기술에 접근가능 하게 해주는 설계 원칙

트랜잭션 추상화와 같이 기술적으로 복잡한 것들은 추상화를 통해 low level의 기술 구현 부분과 기술을 사용하는 인터페이스로 분리 (예를 들어 데이터베이스 종류에 관계 없이 동일하게 적용할 수 있는 트랜잭션 처리 방식)

 

IOC/DI(Inversion Of Control,Dependency Injection)

제어의 역전 / 의존성 주입

DI는 유연하게 확장 가능한 객체를 만들어 두고 객체간 의 의존관계는 외부에서 다이나믹하게 설정

스프링을 사용하면 xml 파일에서 bean을 생성해두고 Autowired를 이용해서 자동 주입할 수 다.

new 라고 따로 객체를 생성하지 않아도 되기때문에, 

각 클래스와 인터페이스 사이, 클래스와 클래스 사이의 has-a 관계를 풀고 구현 및 유지보수의 확장성이 높아 진다.

 

+스프링은 설정 파일이나 어노테이션을 통해 객체 간의 의존 관계를 설정할 수 있다.

따라서 객체는 의존하고 있는 객체를 직접 생성하거나 검색할 필요가 없다.

+IOC Container

객체의 생성,관계 설정,사용, 제거 등의 작업을 애플리케이션 코드 대신 독립된 컨테이너가 담당

컨테이너가 코드 대신 오브젝트에 대한 제어권을 갖고 있기 때문에 제어의 역전이라고 부름

이런 이유로 Spring Container를 IOC container라고도 함

스프링에서 IOC를 담당하는 컨테이너는 BeanFactory,ApplicationContext가 있음

Spring DI Container가 관리하는 객체를 빈BEAN이라고 하고 이 빈들의 생명 주기를 관리하는 의미로 Spring DI Container를 BeanFactory라고 부른다.

beanFactory에 여러 가지 기능들을 추가한 것을 ApplicationContext라고 함

beanFactory- bean 등록+생성+조회+반환

ApplicationContext 등록+생성+조회+반환 각종 부가 서비스

 

AOP(Aspect Oriented Programming)

관점 지향 프로그래밍

관심사의 분리를 통해서 모듈화 하는 것. 

동작이 같은 코드들을 모듈화해서 여러번 작성하지 않고 하나의 메서드로 만들어서 모듈화!!한 다음  

AOP의 Before,After어노테이션을 이용해서 필요한 부분에 코드를 실행시켜 보도록 하는 것

 

bean 생성범위

스프링 빈은 기본적으로 싱글톤으로 만들어진다.

그러므로 컨테이너가 제공하는 모든 빈의 인스턴스들은 항상 동일함

컨테이너가 항상 새로운 빈을 반환하고 싶게 만들 때는 scope를 prototype으로 바꿔줘야함

 

MVC패턴

M=Model

어플리케이션 상태의 캡슐화

상태 쿼리에 대한 응답

어플리케이션 기능 표현

변긍을 view에 통지

 

V=View

모델을 화면에 시각적으로 표현

모델에게 업데이트 요청

사용자의 입력을 컨트롤러에 전달

컨트롤러가 view를 선택하도록 허용

 

C=Controller

어플리케이션의 행위 정의

사용자 액션을 모델 업데이트와 mapping 

응답에 대한 view 선택

 

Spring MVC

Spring은 DI나 AOP같은 기능 뿐만 아니라 ,Servlet기반의 WEB개발을 위한 MVC Framework를 제공

 

3가지 구성요소를 갖고 있따.

1. DispatcherServlet(Front controller)

모든 클라이언트의 요청을 전달 받는다.

-Controller에게 클라이언트의 요청을 전달하고 Controller가 리턴한 결과값을 View에게 전달하여 알맞은 응답을 생성

 

2. HandlerMapping

클라이언트의 요청 URL을 어떤 Controller가 처리할지를 결정.

 

3.Controller 

클라이언트의 요청을 처리한 뒤, Model을 호출하고 그 결과를 DispatcherServlet에 알려준다.

 

작은 3가지도 갖고 있따.

ModelAndView

Controller가 처리한 데이터 및 화면에 대한 정보를 보유한 객체 

 

ViewResolver

Controller가 리턴한 뷰 이름을 기반으로 Controller의 처리 결과를 보여줄 View를 결정

 

View

컨트롤의 처리 결과를 보여줄 응답화면을 생성

 

스프링 MVC의 구조

우선 클라이언트가 요청을 보낸다. 요청을 보내면 제일 먼저 DispatcherServlet이 요청을 받아서 HandlerMapping으로 보낸다. 그러면 HandlerMapping은 요청을 보고 어떤 컨트롤러에서 이 요청을 처리할 지를 결정한다. 컨트롤러는 Service->Dao순으로 요청을 처리한 다음 ModelAndView에 변경된 정보와 어떤 뷰에서 처리해 줄지를 담아서 보내준다. 

이것을 다시 Dispatcher 서블릿은 ViewResolver에게 보내고 ViewResolver는 prefix와 suffix에 필요한 정보를 담아서 url을 완성하고 이것을 다시 dispatcher서블릿에 보내주고 dipatcherServlet은 이 url에 해당하는 view로 보낸다. 

 

인터셉트

Controller가 요청을 처리하기 전/후로 처리할 수 있따.

로그인,모니터링 정보 수집, 접근 제어 처리 등의 실제 Business Logic과는 분리되어 처리해야 하는 기능들을 넣고 싶을 때 유용하다.

 

인터셉터 만드는 법 

인터셉터를 만들 클래스 하나 만들고 handlerinterceptor인터페이스 implements하고

preHandle오버라이드한 다음 이 메서드에서 세션얻어오고 세션안에 멤버DTO 얻어 오고 있으면 그냥 return true 없으면 false해서 인터셉터 해버린다.

 

package com.ssafy.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.HandlerInterceptor;

import com.ssafy.member.model.MemberDto;

//@SuppressWarnings("deprecation")
//public class ConfirmInterceptor extends HandlerInterceptorAdapter {
// spring 5.3 부터는 HandlerInterceptor implements
public class ConfirmInterceptor implements HandlerInterceptor { 

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		HttpSession session = request.getSession();
		MemberDto memberDto = (MemberDto) session.getAttribute("userinfo");
		if(memberDto == null) {
			response.sendRedirect(request.getContextPath() + "/user/login");
			return false;
		}
		return true;
	}
	
}

이거 까지 구현하고 웹의 서블릿 컨텍스트 인터셉트 설정을 걸어준다.

 

<beans:bean id="confirm" class="com.ssafy.interceptor.ConfirmInterceptor"/>

	<interceptors>
		<interceptor>
		
			<!-- <mapping path="/board/*"/> -->
			<mapping path="/board/write"/>
			<mapping path="/board/view"/>
			<mapping path="/board/modify"/>
			<mapping path="/board/delete"/>
			<!-- <exclude-mapping path="/user/log*"/> -->
			
			<!-- <beans:bean class="com.ssafy.interceptor.ConfirmInterceptor"/> -->
			<beans:ref bean="confirm"/>
		</interceptor>
	</interceptors>

서블릿 안의 코드 요렇게 하면 사용이 가능하다.

 

딴 얘기지만

**페이징 처리는 boardServiceImpl에서 한다 

 

REST(Representational State Transfer)

Rest는 하나의 URI는 하나의 고유한 리소르를 대표하도록 설계된다는 개념에 전송방식을 결합해서 원하는 작업을 지정한다. HTTP URI를 통해 제어할 자원을 명시하고 HTTP Method을 통해 해당 자원를 제어하는 명령을 내리는 방식의 아키텍처

 

@RestController Controller가 REST방식을 처리하기 위한 것임을 명시

@ResponseBody JSP 같은 뷰로 전달되는 것이 아니라 데이터 자체를 전달.

@PathVariable URL에 있는 값을 파라미터로 추출

@CrossOrigin Ajax의 크로스 도메인 문제를 해결

@RequestBody JSON데이터를 원하는 타입으로 바인딩

 

405 스프링 부트로 서버 개발 도중 발생한 문제입니다. 

공식문서를 찾아보니 HTTP 405 상태 코드를 허용되지 않는 메서드로 정의하고 있으며 요청 줄에 지정된 메서드가 요청 URI로 식별되는 리소스에 허용되지 않는 상황이라고 합니다.