서버에서 동작하는 Java 기반의 웹 애플리케이션을 만들기 위해 Spring Framework(줄여서 Spring) 반드시 익혀야 한다!
[학습목표]
Spring Framework이 무엇인지 이해할 수 있다.
Spring Framework을 왜 배워야하는지 이해할 수 있다.
Spring Framework의 아키텍처를 버드 아이 뷰 관점에서 이해할 수 있다.
Spring Framework 모듈이 무엇이고 Spring Framework에서 지원하는 모듈에는 어떤 것이 있는지 이해할 수 있다.
Spring Boot이 무엇이고 Spring Boot을 왜 사용해야하는지 이해할 수 있다.
[Spring Initializr]
Spring Boot 실행 환경과 필요한 모듈을 포함하는 템플릿 프로젝트 생성
https://start.spring.io/
Lombok, Spring Web 모듈 선택 및 다운로드해서 인텔리제이에서 열어준다
[Framework]
틀, 뼈대.
프로그래밍 상에서의 Framework : 기본적으로 프로그래밍을 하기 위한 틀이나 구조를 제공. 개발자가 애플리케이션의 핵심 로직을 개발하는 것에 집중할 수 있도록 해줌
[Framework vs Library]
애플리케이션 흐름의 주도권이 개발자에게 있는지(Library), Framework에 있는지에 따라 다름
-> IoC. Inversion Of Control. 제어의 역전
[왜 Spring Framework인가?]
기업용 엔터프라이즈 시스템 : 기업의 업무를 처리해주는 시스템. 서버의 자원 효율성, 보안성, 시스템의 안전성, 확장성 등 충분히 고려해야
Spring Framework는 객체 지향 설계 원칙에 잘 맞는 재사용, 확장 가능한 애플리케이션 개발 스킬을 향상시킬 수 있음. 보다 나은 성능과 서비스의 안전성이 필요한 복잡한 기업용 엔터프라이즈 시스템을 제대로 구축하기 위한 능력 기를 수 있다.
JSP -> Servlet -> Spring MVC -> Spring Boot
JSP 방식으로 개발할 때는 프런트/백엔드 영역 구분하지 않았음
Servlet : Spring 사용시 내부적으로 Servlet 사용
Spring MVC : Spring MVC 설정파일 web.xml 이외 다른 설정 파일들 필요. 복잡한 설정
Spring Boot : Spring의 복잡한 설정 작업을 Spring이 대신 처리해줌
[Spring Framework의 특징]

Spring 삼각형
POJO(Plain Old Java Object) : Java로 생성하는 순수한 객체. 플레인 요거트
Spring은 POJO 프로그래밍 지향하기 위해 세 가지 기술 지원
[POJO]
POJO(Plain Old Java Object) : Java로 생성하는 순수한 객체. 플레인 요거트
POJO 규칙
1. Java나 Java의 스펙(사양)에 정의된 것 이외에는 다른 기술이나 규약에 얽매이지 않아야 한다
2. 특정 환경에 종속적이지 않아야 한다
public class MessageForm extends ActionForm{ // Struts 기술 사용하기 위해 ActioForm 상속.
String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
public class MessageAction extends Action{ // Struts 기술의 Action 클래스 상속
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
MessageForm messageForm = (MessageForm) form;
messageForm .setMessage("Hello Wolrd");
return mapping.findForward("success");
}
} // Java는 다중상속 지원하지 않는다. extends 사용하여 상속시 객체지향 설계 기법 적용 불가
[POJO 프로그래밍이 필요한 이유]
특정 환경이나 기술에 종속적이지 않으면 재사용 가능, 확장 가능한 유연한 코드를 작성할 수 있다.
저수준 레벨의 기술과 환경에 종속적인 코드를 애플리케이션 코드에서 제거함으로써 코드가 깔끔해진다.
디버깅하기 쉽다 (단순)
객체지향적인 설계를 제한없이 적용할 수 있다.
객체 지향 설계
https://ko.wikipedia.org/wiki/SOLID(객체지향_설계)
https://itvillage.tistory.com/entry/객체지향-설계-원칙-SOLID-원칙
[IoC(Inversion of Control)/DI(Dependency Injection)]
IoC : 애플리케이션 흐름의 주도권이 뒤바뀐 것. 애플리케이션 흐름의 주도권을 Spring이 갖는다
(Library는 주도권 개발자에게, Framework는 주도권 Framework에)
DI : (객체간) 의존성 주입. 클래스 다이어그램 틈틈이 그려보기
클래스끼리 사용하고자 하는 객체를 생성해서 참조하면 의존 관계 성립
엔드포인트 : 클라이언트가 서버 자원(리소스)을 이용하기 위한 끝지점
public class CafeClient {
public static void main(String[] args) {
MenuService menuService = new MenuService();
MenuController controller = new MenuController(menuService);
List<Menu> menuList = controller.getMenus();
}
}
// CafeClient
public class MenuController {
private MenuService menuService;
public MenuController(MenuService menuService) { // MenuController 생성자로 MenuService의 객체 전달받고 있음 (의존성주입)
this.menuService = menuService;
}
public List<Menu> getMenus() {
return menuService.getMemuList();
}
}
// MenuController
public class MenuService {
public List<Menu> getMenuList() {
return null;
}
}
// MenuService
클래스의 생성자로 객체 전달 받는 코드 있으면 의존성 주입 이루어짐
[AOP(Aspect Oriented Programming)]
관심 지향 프로그래밍
Aspect : 공통적으로 적용되는 기능에 대한 공통 관심 사항을 의미 (↔︎ 핵심 관심 사항)
AOP : 애플리케이션의 핵심 업무 로직에서 로깅, 보안, 트랜잭션 같은 공통 기능 로직을 분리
핵심 로직에서 공통 기능 분리하는 이유 : 코드의 간결성 유지, 객체 지향 설계 원칙에 맞는 코드 구현, 코드의 재사용
[AOP가 적용되지 않는 JDBC 트랜잭션]
public class Example2_11 { // AOP가 적용되지 않는 JDBC 트랜잭션
private Connection connection;
public void registerMember(Member member, Point point) throws SQLException {
connection.setAutoCommit(false); // 1
try {
saveMember(member); // 2
savePoint(point); // 2
connection.commit(); // 3
} catch (SQLException e) {
connection.rollback(); // 4
}
} // registerMember() 메서드 내 비지니스 로직 수행하는 코드 : 2 saveMember(), savePoint()
// 1, 3, 4 는 2를 트랜잭션으로 묶어서 처리하기 위한 기능 -> 중복시 AOP로 공통화 해서 재사용
private void saveMember(Member member) throws SQLException {
PreparedStatement psMember =
connection.prepareStatement("INSERT INTO member (email, password) VALUES (?, ?)");
psMember.setString(1, member.getEmail());
psMember.setString(2, member.getPassword());
psMember.executeUpdate();
}
private void savePoint(Point point) throws SQLException {
PreparedStatement psPoint =
connection.prepareStatement("INSERT INTO point (email, point) VALUES (?, ?)");
psPoint.setString(1, point.getEmail());
psPoint.setInt(2, point.getPoint());
psPoint.executeUpdate();
}
}
[AOP가 적용된 JDBC 트랜잭션]
@Component
@Transactional // -> Spring 내부에서 애노테이션 정보 활용해서 AOP 기능 통해 트랜잭션 적용
public class Example2_12 {
private Connection connection;
public void registerMember(Member member, Point point) throws SQLException {
saveMember(member);
savePoint(point);
}
private void saveMember(Member member) throws SQLException {
// Spring JDBC를 이용한 회원 정보 저장
}
private void savePoint(Point point) throws SQLException {
// Spring JDBC를 이용한 포인트 정보 저장
}
}
트랜잭션 (Transaction) : 데이터를 처리하는 작업단위 . (커밋, 롤백)
커밋 : 모든 작업이 성공적으로 수행되었을 경우 수행한 작업을 데이터베이스에 반영
롤백 : 작업이 하나라도 실패하면 이전에 성공한 작업들을 작업 수행 이전 상태로 되돌리는 것 (ex. 계좌이체 실패)
[PSA(Portable Service Abstraction)]
Abstraction : 추상화. 본질적인 특성만을 추출해서 일반화 하는 것
추상화 하는 이유 : 상위 클래스에 정의된 일반화 된 특징을 하위 클래스의 특징에 맞게 사용. 서비스 이용하기 위한 접근 방식을 일관적으로 유지하면서 애플리케이션에서 사용하는 기술이 변경되더라도 최소한의 변경만으로 변경된 요구 사항을 반영하기 위함
적용 분야 : 트랜잭션, 메일, Spring data 등