[Web] 13. Spring
JSP Model1, Model2, and Spring MVC pattern
JSP(Java Server Page)는 Servlet의 확장된 기술로 브라우저에 표현하기 위한 HTML 코드에 JAVA코드를 혼용하여 사용할 수 있게 한다. 이로써 디자인과 로직 개발을 분업화시켜 효율적인 코드를 생산할 수 있다.
JSP가 동작하는 구조
- 클라이언트가 브라우저를 통해서 서버에 HTTP 프로토콜을 요청한다.
- 서버는 컨테이너에게 처리를 요청하고 컨테이는 요청받은 해당 파일을 찾아낸다.
- 찾은 파일을 Servlet으로 변환한다. (이미 변환되어 있다면 바로 실행)
- Servlet 파일을 실행할 수 있도록 Class파일로 컴파일한다.
- 컴파일된 Class 파일을 메모리에 넣고 실행 결과를 웹 서버에서 전달.
- 웹서버는 브라우저가 인식할 수 있는 정적페이지를 구성하여 요청에 응답.
MVC패턴이란?
Model, View, Controller의 합성어로 소프트웨어 디자인 패턴을 말한다.
Model: 백그라운드에서 동작하는 로직을 처리한다.
View: 사용자가 보게 될 화면을 출력한다.
Controller: 사용자의 입력처리와 흐름 제어를 담당한다.
Model1 Architecture
- JSP, Servelt, Bean 등으로 구성되는 형태로 JSP에는 프리젠테이션 레이어 & 비즈니스 레이어를 포함하고 업무부분을 JavaBean이나 Servlet에서 구현하기도 한다.
- Model - View - Controller로 구분하기 모호하긴하지만 궂이 따지자면 그림과 같이 JSP에서는 주로 View와 Controller의 역할을 JavaBean / Servlet에서는 주로 Model의 역할을 하지만 Controller의 역할을 하기도 한다.
장점 | 단점 |
페이지의 흐름이 단순해서 개발 팀원들의 수준이 높지 않아도되 중소형 프로젝트에 적합하다. | 웹 애플리케이션이 복잡해질수록 유지 보수가 힘들어진다. |
디자이너와 개발자의 소통에 문제가 생긴다면 충돌이 발생할 수 있다. |
Model2 Architecture
- 사용자 요청에 대하여 Controller는 Model에게데이터 조회, 비즈니스 로직의 처리를 요청(②)하고 Model로 부터 정보를 받아 View에게 전달(③)한다. 최종적으로 View는 정적데이터를 구성하여 사용자에게 Response(⑥)한다.
장점 | 단점 |
효과적으로 분리되어 구성된다면 개발자와 디자이너의 작업이 분리되어 역할과 책임 구분이 명확해진다. | 구조화를 위해 개발의 복잡도가 증가한다. |
로직과 디자인 개발의 분리로 인해 웹애플리케이션이 구조화되어 유지보수 및 확장이 용이하다. | MVC구조에 대한 높은 수준의 이해도가 요구된다. |
Spring Framework / Spring Boot
Spring Framework란,
스프링 프레임워크는 어떤 플랫폼에서도 종합적인 프로그래밍과 자바 기반의 현대 엔터프라이즈 어플리케이션의 Configuration Model을 제공한다. 스프링의 핵심요소는 어플리케이션 단위의 인프라를 제공한다는 것입니다. 스프링은 기업용 어플리케이션의 plumbing에 초점을 맞추고 있습니다. 그래서 개발팀은 특정 배포 환경에서 불필요한 시도없이 어플리케이션의 비지니스 로직에 초점을 맞출 수 있습니다.
- 자바(JAVA) 플랫폼을 위한 오픈소스(Open Source) 어플리케이션 프레임워크
- 자바 엔터프라이즈 개발을 편하게 해주는 오픈 소스 경량급 애플리케이션 프레임워크
- 자바 개발을 위한 프레임워크로 종속 객체를 생성해주고, 조립해주는 도구
- POJO(Plain Old Java Object) BEAN CONTAINNER
특징
- 크기와 부하의 측면에서 경량
- 제어 역행(IoC)를 통하여 어플리케이션의 느슨한 결합을 도모
- 관점지향(AOP) 프로그래밍을 위한 풍부한 지원을 함.
- 어플리케이션 객체의 생명주기와 설정을 포함하고 관리한다는 점에서 일종의 컨테이너라고 할 수 있음.
- 간단한 컴포넌트로 복잡한 어플리케이션을 구성하고 설정할 수 있음.
참고링크: https://opentutorials.org/course/2428/13594
Spring Framework 기본 개념 - 개발자로 살아가기
Java Framework 역사 Spring Framework 소개 스프링 프레임워크는 어떤 플랫폼에서도 종합적인 프로그래밍과 자바 기반의 현대 엔터프라이즈 어플리케이션의 Configuration Model을 제공한다. 스프링의 핵심��
opentutorials.org
Spring Boot란?
스프링 프레임워크를 사용하는 프로젝트를 아주 간편하게 설정할 수 있는 스프링 프레임워크의 서브 프로젝트라고 할 수 있다.
- 단독실행 가능한 스프링 애플리케이션을 생성한다.
- Spring Boot는 최소한의 초기 스프링 구성으로 가능한 한 빨리 시작하고 실행할 수 있도록 설계되었다.
- 웹 컨테이너를 내장하고 있어 최소한의 설정으로 쉽게 웹 애플리케이션을 만들 수 있다.
스프링부트 참조링크: https://goddaehee.tistory.com/238
[스프링부트 (1)] 스프링부트 시작하기 (SpringBoot 프로젝트 설정 방법)
[스프링부트 (1)] 스프링부트 시작하기 (SpringBoot 프로젝트 설정 방법) 안녕하세요. 갓대희 입니다. 이번 포스팅은 [ 스프링 부트 기초. 스프링 부트란? 그리고 스프링 부트 프로젝트 생성 방법
goddaehee.tistory.com
POJO
Plain Old Java Object
- 특정 인터페이스나 클래스를 상속하지 않고, 순수하고 Getter, Setter로만 구성된 자바 객체를 말한다. (어디에도 종속되지 않는다.)
- 다른 곳에 종속되지 않는다는 것은 해당 클래스를 사용하기 위해 어떤 프레임워크나 외부 환경이 필요없다는 것이다.
- 즉, Spring MVC를 걷어내도 POJO들은 정상적으로 동작되어야 한다.
- POJO와 설정 정보(Configuration metadata)를 Spring IoC Container에 주입시키면 Bean으로 등록, 사용이 가능하다.
POJO를 사용하면, 특정 라이브러리나 컨테이너의 기술에 종속적이지 않고 가장 일반적인 형태로 코드를 작성할 수 있는데 이를 통해 코드에 대한 테스트 작업을 좀 더 유연하게 할 수 있다.
IoC
Inversion Of Control
- 제어권이 역전되었다. (의존 관계 주입)
- 어떤 객체가 사용할 객체(의존관계인 객체)를 직접 선언하여 사용하는 것이 아니라, 어떤 방법을 사용하여 주입 받아 사용하는 것.
/*
일반적인 제어권: 자기가 사용할 의존성은 자기가 만들어서 사용
*/
@Service
public class CarService {
private CarRepository carRepository = new CarRepository();
}
/*
Inversion Of Control
다른 누군가가 의존성을 밖에서 준다.(제어권의 역전)
의존성을 주입해주는 일:Dependency Injection(일종의 IOC)
*/
@Service
public class CarService {
// CarRepository를 사용은 하지만 만들지는 않는다.
private CarRepository carRepository;
/*
생성자를 통해서 받아온다.
따라서 의존성을 관리하는 일은 CarService가 하는 일이아니다. 누군가 밖에서 해주는 것이다.
*/
public CarService(CarRepository carRepository){
this.carRepository = carRepository;
}
}
DI
Dependency Injection
의존성 주입, Spring 의 Container 들은 Bean 객체들을 관리하는 데 있어서 DI 를 이용하며 이를 통해 Life Cycle 을 용이하게 관리할 수 있으며 이 것이 스프링 프레임워크의 핵심적인 동작이라고 할 수 있다.
즉, 프레임워크 레벨의 관리를 통해 개발자는 객체들간의 의존성에 신경을 덜 쓰고 Coupling 을 줄일 수 있으며 높은 재사용성과 가독성있는 코드를 만들어낼 수 있다.
- Dependency Reduction : 객체 상호 간 의존성 관계를 줄여준다.
- Reusable Structure : 코드의 재사용과 조합이 용이하다.
- Readability : 코드들이 분리되다보니 가독성이 뛰어나진다.
- Loose Coupling & Easy to change : 구조는 변화에 민감하지 않을 수 있다.
1. Field Injection
public class Sample {
@Autowired
private Example example;
}
- Single Responsibility Principle Violation
: 너무나 쉬운 의존성의 주입은 하나의 클래스가 지나치게 많은 기능을 하게됨으로써 초기 설계의 목적성이자 "객체는 그에 맞는 동작만을 한다." 는 원칙에 위배되기 쉽다.
위배된 경우 리팩토링의 비용은 크다.
- Dependency Hiding
: 추상화된 의존관계는 의존성을 검증하기 힘들게 만든다.
- DI Container Coupling
: Field Injection 을 사용하면 해당 클래스를 곧바로 Instant 화시킬 수 없다. 이 부분 때문에 Constructor Injection 이 권장되는 이유이기도 하다.
가령 Container 밖의 환경에서 해당 클래스의 객체를 참조할 때, Dependency 를 정의해두는 Reflection 을 사용하는 방법 외에는 참조할 수 있는 방법이 없다.
DI Framework 는 Field Injection 된 클래스의 Instance 화에 대해서 Null Pointer Exception 을 만들어낼 것이다.
- Immutability
: Field Injection 된 객체는 final 을 선언할 수 없으므로 가변적(Mutable)이다. 객체는 변경될 수 있으며 이에 대한 대응에는 큰 비용이 든다.
2. Setter Injection
public class Sample {
private Example example;
@Autowired
public void setExample(Example example) {
this.example = example;
}
}
Field Injection 으로 인한 패턴적 위험성을 상당 부분 해소한다. Optional Injection 의 경우 권장되는 방식이다.
@Required 어노테이션을 이용하면 의존성이 필요한 Setter 를 만들 수 있다.
3. Constructor Injection
public class Sample {
private final Example example;
@Autowired
public Sample(Example example) {
this.example = example;
}
}
코드를 통해 알 수 있듯, final 선언이 가능하며 Immutability 에 대한 해소가 가능하며 의존성의 순환 참조(Circular Dependency) 에 대한 예방이 가능하다.
순환 참조 시 위의 방법을 이용한 코드는 BeanCurrentlyCreationExeption 을 발생시킨다.
역시 위에서 언급된 Container Coupling 문제도 해결이 되는데, 생성자를 통한 Injection 이므로 즉각적인 Instance 화 등에 대한 문제도 해결된다.
많은 예제 코드들이 Field Injection 방식을 사용하고 있으나 Constructor Injection 의 사용이 권장된다.
추가로 참조한 바에 의하면 Spring Team 에서는 Setter 방식을 좀 더 권장하며 이유는 생성자가 지나치게 복잡해질 수 있기 때문이라고 한다.
출처: https://jins-dev.tistory.com/entry/Spring-DIDependency-Injection-의-정의와-사용
AOP
Aspect Oriented Programming
관점지향 프로그래밍
핵심 기능과 공통 기능을 분리 시켜놓고, 공통 기능을 필요로 하는 핵심 기능들에서 사용하는 방식.
DTO
Data Transfer Object
- 이름과 같이 계층 간 데이터 교환을 위해 사용하는 객체다. 여기서 말하는 계층이란, View - Controller - Service - DAO와 같은 각 계층을 말한다.
- VO와 혼용되어 쓰이나, 이는 보통 DTO를 지칭하는 말이다.
- 데이터를 담을 private 변수와 그 변수를 조작할 수 있는 Getter, Setter 메소드로 구성되어 있다.
DAO
Data Access Object
데이터에 접근하는 객체로써, DB에서 데이터를 가지고 오는 역할을 수행한다.(이후에, 가져온 데이터를 처리하는 것은 Service에서 하고, 처리된 데이터는 Controller를 통해서 적절한 View에 전달되는 것이 MVC 구조다.)
package com.first.begin.sample.dao;
public interface SampleDao {
public String selectSampleData() throws Exception;
}
package com.first.begin.sample.dao;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository("sampleDao")
public class SampleDaoImpl implements SampleDao {
@Autowired
protected SqlSessionTemplate sqlSession;
@Override
public String selectSampleData() throws Exception {
return sqlSession.selectOne("spl.selectDisposableTable");
}
}
스프링 개발에서 흔히 사용하는 인터페이스를 이용한 패턴이다.
Dao를 구현한 DaoImpl 클래스를 살펴보자.
7번째 줄에서 @Repository 애노테이션을 통해 Dao의 역할을 할 것이라고 선언해주었다.
10~11번째 줄에선 SqlSessionTemplate 빈을 사용할 수 있게 했고, DB와의 연결을 열고 닫아주는 역할을 간편하게 대신해줄 것이다.
13~16번째 줄은 실제 데이터를 가져오기 위한 코드로, 만들어준 sqlSession을 통해 mapper로 만든 쿼리의 이름을 호출해서 데이터를 가져오는 과정을 쉽고 단순하게 만들어주었다.