tomcat file 설치
- mac
- setup.sh
- Window
- setup.bat 실행
종료
- ./shutdown.sh
톰캣
- Servlet interface(Spec)구현체
- Servlet Container 중 하나
컨테이너 기반의 가상화 vs 하이퍼바이저 기반의 가상화(OS 가상화)
도커
- 컨테이너 기반의 가상화
도커 허브
- 도커에서 제공하는 이미지 저장소
도커 컴포즈
- 다중 컨테이너를 정의하고 실행하기 위한 도구
- YAML 파일을 사용하여 다중 컨테이너를 구성함
Info
YAML
- YAML Ain’t Markup Language
- 데이터를 저장하고 전달하기 위한 형식 (주로 설정파일에 사용 됨) -https://teddylee777.github.io/python/yaml/
docker command docker run —name mysql-test -e MYSWL_ROOT_PASSWORD=1234 -d -p 3309:3306 mysql:latest
- docker run
- 도커 실행
- —name mysql-test
- 도커 컨테이너 네임 mysql-test로 지정
- -e MYSQL_ROOT_PASSWORD=1234
- -e 환경 변수 설정
- 비밀번호를 1234
- -d
- 백그라운드 실행
- -p 3309:3306
- 포트 설정
- 인바운드 포트 3309
- 아웃바운드 포트 3306
- mysql:latest - 사용할 도커 이미지 명
docker ps
- 실행중인 컨테이너 출력
docker docker exec -it mysql-mvc bash
- exec
- Execute
- 실행
- -it
- interactive
- 표준 입력 활성화
- tty(가상 터미널)
TDD
- Test Driven Development
- 테스트 주도 개발
- 프로덕션 코드보다 테스트를 먼저 작성하는 개발 방법
- TFD(Test First Development) + 리팩토링
- 기능 동작을 검증
BDD
- Behavior Driven Development
- 행위 주도 개발
- 시나리오 기반으로 테스트 코드를 작성하는 개발 방법
- 하나의 시나리오는 given , when , then 구조를 가짐
테스트 코드
- assertThatCode
- 무조건 성공해야하는 코드
- assertThatThrownBy
- 무조건 에러가 발생해야하는 코드
- 에러가 발생하지 않으면 실패
람다식(익명함수)
- (타입 매개변수 , … ) → { 실행문; } ex) int sum(int a , int b) (a,b) → return a+b;
생략 조건 매개변수의 타입이 생략 가능하다.
- MaxNumber maxNumber = (str) → {System.out.println(str);}; 매개변수가 한개인 경우 소괄호 생략이 가능하다.
- MaxNumber maxNumber = str → {System.out.println(str);}; 코드블록 내 실행하는 코드가 한줄인 경우 중괄호 생략이 가능하다.
- MaxNumber maxNumber = (str) → System.out.println(str); 드블록 내 실행하는 코드가 return문만 있는 경우 중괄호와 return의 생략이 가능하다.
- MaxNumber maxNumber = (str) → { return String.valueOf(str);};
- MaxNumber maxNumber = (str) → String.valueOf(str); 매개변수가 없는 경우 소괄호만 표시해준다.
- MaxNumber maxNumber = () → System.out.println(“매개변수 없음”);
- @ParameterizedTest
- org.junit.jupiter:junit-jupiter-params:5.7.0
- 의존성을 추가해 주어야 사용 가능
- 여러 값을 동시에 테스트 할 때 사용
- ValueSource , CSVSource , enum 등 여러가지 사용 가능
- @ValueSource
- 리터럴 값의 배열에 대한 접근을 제공하는 어노테이션
테스트 코드 실습
- RandomPasswordGenerator 를 통해서 만들 때
- interface 를 추가하여 같은 메소드를 사용하게 한다
그리고 인터페이스를 상속 받은 케이스 2가지 ( Correct , Wrong)
- 장점 느슨한 결합을 만들 수 있다
- interface 를 추가하여 같은 메소드를 사용하게 한다
그리고 인터페이스를 상속 받은 케이스 2가지 ( Correct , Wrong)
- 내 생각 :
객체지향
- 추상화
- 다형성
- 캡슐화
- 상속
추상화
- Abstraction
- 불필요한 부분을 제거하고 핵심만 나타낸 것 ? 다형성
- Polymorphism
- 하나의 타입으로 여러 객체를 참조하는 것 ? 캡슐화
- Encapsulation
- 객체의 내부를 외부로부터 감추는 것
- 인터페이스만 공개해서 변경하기 쉬운 코드를 만들기 위함 상속
- Inheritance
- 부모로부터 물려받는 것
SOLID
- SRP : 단일 책임 원칙
- OCP : 개방 폐쇄의 원칙
- LSP : 리스코프 치환의 원칙
- ISP : 인터페이스 분리의 원칙
- DIP : 의존성 역전의 원칙
SRP
- Single Responsibility Principle
- 단일 책임 원칙
- 하나의 책임을 가짐 OCP
- Open/Closed Principle
- 개방 폐쇄의 원칙
- 확장에는 열려있고 변경에는 닫혀있다
- 기존 코드를 변경하지 않고 기능을 추가 할 수 있어야 한다 LSP
- Liskov’s Substitution Principle
- 리스코프 치환의 원칙
- 상위 타입의 객체를 하위 타입의 객체로 치환해도 동작에 문제가 없어야 한다 ISP
- Interface Segregation Principle
- 인터페이스 분리의 원칙
- 많은 기능을 가진 인터페이스를 작은 단위로 분리
- 클라이언트에게 필요한 인터페이스만 구현 DIP
- Dependency Inversion Principle
- 의존성 역전의 원칙
- 의존 관계를 맺을 때 자주 변경되는 쪽이 아니라 거의 일어나지 않는 쪽에 의존
- 추상화 된 인터페이스나 상위 클래스를 둬서 영향을 덜 받게 한다
객체지향 패러다임
- 적절한 객체에게 적절한 책임을 할당하여 서로 메세지를 주고 받으며 협력하도록 하는 것
- 점점 증가하는 SW 복잡도를 낮추기 위해 객체지향 패러다임 대두
- 개인적으로 생각하는 두 가지 중요 포인트
- 클래스가 아닌 객체에 초점을 맞추는 것
- 객체들에게 얼마나 적절한 역할과 책임을 할당하는지
절차지향 프로그래밍 vs 객체지향 프로그래밍
- 다른 객체에서 불러오는지 아닌지 차이?
cohesion
- 결합도 coupling
- 응집도
high cohesion, loose coupling 변경이 생겼을 때 관련 기능이 한 곳에 모여있고 영향(변경으로 인한 수정해야 할 부분)이 적음
메소드를 이용하여 한번에 테스트 할 때 위와 같이 사용한다.
enum class 안에 추상 메소드 만들고 각 상수가 특정 클래스의 인스턴스를 생성하는 방식으로 구현할 수 있음
학점계산기
과목(corse)
문제점
- 과목에서 학점을 계산하는게 아니라 gradeCalculate 에서 계산하고 있음
- 해당 부분의 로직이 여러 곳에서 사용된다면 모두 바꿔줘야함 ?
- 응집도가 약하다
- getter로 가져와서 처리하는 것 보다 해당 정보를 가진 객체에세 메세지를 줘서 작업을 하게 함
일급 컬렉션
- 변수 1개
- List 로 된 객체만 가지는 클래스?
요리
객체들 끼리 비교 할 때는 Equals and HashCode 가 있어야 됨
- assertThatCode() :
- isInstanceOf() :
- hasMessage("") : 메세지 확인
HTTP
-
서버와 클라이언트가 웹에서 데이터를 주고 받기 위한 프로토콜(규약)
-
HTTP/1.1 , HTTP/2
- TCP 기반
-
HTTP/3
- UDP 기반
-
클라이언트 서버 모델
-
무상태 프로토콜(StateLess)
- 서버가 클라이언트 상태를 유지하지 않음
- 해결책 : Keep-Alive 속성 사용 단점 : 스레드 부족으로 다른 유저를 못 받음
-
비 연결성
- Connectionless
- 서버가 클라이언트 요청에 대해 응답을 마치면 맺었던 연결을 끊어 버림
- 해결책 : 쿠키(클라이언트에 정보 저장) , 세션(서버에 정보 저장), JWT
무상태와 비 연결성 이유
- 불특정 다수와 통신이 가능하도록 설계된 프로토콜
- 다수의 클라이언트들의 상태 또는 연결을 유지시 리소스 낭비가 심함
- 상태 또는 연결을 유지하지 않는 대신 더 많은 연결을 할 수 있도록 설계 됨
Web 계산기 만들기 (Requst 만들기)
GET http://localhost:8080/calculate?operand1=11&operator=*&oerand2=55
HTTP
- RequestLine 부분의 값을 추출해서 계산
여기서 HTTPRequest의 구조
- RequestLine
- HttpMethod
- path
- queryString
// 나누기(/)는 디코딩 해서 써야됨 안그러면 %2F 로 들어옴
Thead 알아보고 정리하기
메인스레드 처리 → 스레드 생성해서 할당
메인 스레드 처리
요청이 들어오면 스레드 생성
implements Runnable
Runnable 인터페이스를 구현해서 새로운 스레드에서 실행
ClientRequestHandler 구현
문제점 :
- 스레드는 생성 될 때마다 메모리를 할당 받음 이 작업은 굉장히 비싼 작업이
- 동시 접속자가 많아질 경우
- CPU ContextSwitching 증가
- CPU 사용량 증가
- 메모리 사용량 증가
- 결론 : 서버가 다운 될 가능성이 있음
- 스레드풀
- 스레드를 고정된 갯수만큼 생성
- 재활용
스레드풀을 이용해서 스레드 갯수 제한
CGI
- Common Gateway Interface
- 웹 서버와 애플리케이션 사이에 데이터를 주고받는 규약
- CGI 규칙에 따라서 만들어진 프로그램을 CGI 프로그램이라고 함
- CGI프로그램 종류로는 컴파일 방식(C,C++,JAVA 등)과 인터프리터 방식(PHP,Python 등)이 있음
웹서버에서 스크립트 엔진을 실행시키고 스크립트 파일을 해석해서 값을 리턴
서블릿
- Servlet
- Server + Applet 의 합성어
- 자바에서 웹 애플리케이션을 만드는 기술
- 자바에서 동적인 웹 페이지를 구현하기 위한 표준
서블릿 컨테이너
- ServletContainer
- 서블릿의 생성부터 소멸까지 라이프 사이클을 관리하는 역할
- 서블릿 컨테이너는 웹 서버와 소켓을 만들고 통신하는 과정을 대신 처리해준다. 따라서, 개발자는 비즈니스 로직에만 집중하면 된다.
- 서블릿 객체를 싱글톤으로 관리
- 상태를 유지(Stateful)하게 설계하면 안됨
- Thread safety 하지 않음
상태를 유지하게 되면 안됨
- 멀티스레드 환경에서 하나의 객체를 공유 ( 싱글턴 ) 시
- 뜻하지않는 결과가 나옴
- 레이스 컨디션 : 여러 프로세스 혹은 스레드가 동시에 하나의 자원에 접근하기 위해 경쟁하는 상태를 레이스 컨디션이라고함
동기화 처리로 개선 가능
Spring Bean
- 디폴트로 싱글턴으로 관리됨
- 상태를 유지하게 설계하면 안됨
- ”상태를 유지한다”는 말은 프로그램이나 시스템이 이전의 상태 정보를 기억하고, 이를 기반으로 동작을 계속할 수 있다는 의미
엔진 컨테이너 차이
- 엔진 : ?
- 컨테이너 : 라이프 사이클을 관리
WAS vs 서블릿 컨테이너
- WAS는 서블릿 컨테이너를 포함하는 개념
- WAS는 매 요청마다 스레드 풀에서 기존 스레드를 사용함
- WAS의 주요 튜닝 포인트는 max thread 수
- 대표적인 WAS로는 톰캣이 있다.
Servlet 인터페이스
- 서블릿 컨테이너가 서블릿 인터페이스에 있는 메소드들을 호출함
- 서블릿 생명주기와 관련된 메소스
- init() , service() , destroy()
- 서블릿 기타 메소드
- getServletConfig()
- getServletInfo()
Servlet
- 필요가 없어도 일일이 구현을 해줘야 됨 ??
GenericServlet
- init , destroy , getServletConfig , getServletInfo 필요할 때만 Overide
HttpServlet
- 요청마다 구현해주면 됨
- doGet(), doDelete , doPost
GenericServlet vs HttpServlet
URL 인코딩 (=퍼센트 인코딩)
- URL로 사용할 수 없는 문자 (예약어 , Non-ASC2 문자(한글)등)를 사용할 수 있도록 인코딩하는 것
- 인코딩 된 문자는 triplet(세 개가 한 세트)로 인코딩 되며 각각을 % 다음에 두 개의 16진수로 표현함
-
- , *
- 예약 문자
Spring MVC Flow
JDBC
- Java DataBase Connectivity
- 자바 애플리케이션에서 DB 프로그래밍을 할 수 있도록 도와주는 표준 인터페이스
- JDBC 인터페이스들을 구현한 구현체들은 각 데이터 베이스 벤더 사들이 제공
DBCP
- 미리 일정량의 DB 커넥션을 생성해서 풀에 저장해 두고 있다가 HTTP 요청에 따라 필요할 때 풀에서 커넥션을 가져다 사용하는 기법
- 참고로 스프링 부트 2.0 부터는 디폴트 커넥션 풀로 HikariCP 사용
주의 사항
- 커넥션의 사용 주체는 WAS 스레드
- 커넥션 갯수는 WAS 스레드 수와 함께 고려해야 함
- 커넥션 수를 크게 설정하면
- 메모리 소모 증가
- 접속자가 많더라도 사용자 대기시간 감소
- 커넥션 수를 작게 설정하면
- 메모리 소모 적음
- 대기 시간이 길어짐
- 적정량 커넥션 객체를 생성해야됨
DataSource
- 커넥션을 획득하기 위한 표준 인터페이스
- HikariCP 의 DataSource 사용
try With Resource 하면 자동으로 자원해제함
- rs.close()
- psmt.close()
- con.close()
connectionPool 적용
변경되는 쿼리문 → 외부로부터 받아오면 됨
psmt 는 외부로부터 전달 받을려면 2번 줄 때문에 안됨
변경되는 부분은 호출자 입장에서 전달
Reflection
- 힙 영역에 로드되어 있는 클래스 타입의 객체를 통해 필드 / 메소드 / 생성자를 접근 제어자와 상관 없이 사용할 수 있도록 지원하는 API
- 컴파일 시점이 아닌 런타임 시점에 동적으로 특정 클래스의 정보를 추출해낼 수 있는 프로그래밍 기법
- 주로 프레임워크 또는 라이브러리 개발 시 사용 됨
- Spring 프레임워크 ( DI, AOP etc )
프런트 컨트롤러 패턴
- 모든 요청을 단일 handler(처리기) 에서 처리하도록 하는 패턴
- 스프링 웹 MVC 프레임워크의 DispatcherServlet (프런트 컨트롤러 역할)이 프런트컨트롤러 패턴으로 구현되어 있음
Forward
- 서블릿에서 클라이언트 ( 웹 브라우저 )를 거치지 않고 바로 다른 서블릿(또는 JSP)에게 요청하는 방식
- Forward 방식은 서버 내부에서 일어나는 요청이기 때문에 HttpServletRequest, HttpServletResponse 객체가 새롭게 생성되지 않음 ( 공유 됨 )
- RequestDispatcher dispatcher = request.getRequestDispatcher( ” 포워드 할 서블릿 또는 JSP ” )
Redirect
- 서블릿이 클라이언트 ( 웹 브라우저 )를 다시 거쳐 다른 서블릿 ( 또는 JSP )에게 요청하는 방식
- Redirect 방식은 클라이언트로부터 새로운 요청이기 때문에 새로운 HttpServletRequest, HttpServletResponse 객체가 생성됨
- HttpServletResponse 객체의 sendRedirect() 이용
톰캣이 HttpServlet을 싱글톤으로 생성 requestHandlerMapping 이 만들어질 때 초기화 되는 코드
에러 :
The absolute uri: [http://java.sun.com/jsp/jstl/core] cannot be resolved in either web.xml or the jar files deployed with this application
출처: https://beagle-dev.tistory.com/82 [언젠간 되어있겠지:티스토리]
-
<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %> 이 JSP 에 추가 되지 않았거나
-
이와 관련된 라이브러리가 추가되지 않았기 때문.
https://tomcat.apache.org/download-taglibs.cgi
위 링크에서 다운로드후 lib 폴더를 WEB_INF 폴더 바로 아래에 추가!
출처: https://beagle-dev.tistory.com/82 [언젠간 되어있겠지:티스토리]
MVC 프레임 워크 만들기
어노테이션 기반 MVC 프레임 워크
- DispatcherServlet
- AnnotationHandlerMapping
- HandlerAdapter
- ViewResolver
DispatcherServlet 의 문제점
- uri로만 구분하기 때문에 requestMethod를 구분 할 수 없음
- 해결 : HandlerKey Class 추가
command - P
- 인텔리제이 인자값 보기
Filter
- Spring framework 동작 전에 실행
webEncodingFilter
servlet 의 Filter
개선
→ interface
→ A 객체가 B 객체를 사용하고 있음 → A가 B를 의존하고 있는 상태
DI
- Dependency Injection
- 의존성 주입
- 한 객체가 다른 객체를 사용할 때 의존성이 있다고 함
- 런타임 시 의존 관계를 맺는 대상을 외부에서 결정하고 주입해 주는 것
- 스프링 프레임워크는 DI 를 지원함
장점
- 의존성 주입을 인터페이스 기반으로 설계하면 코드가 유연해짐
- loose coupling
- 변경에 유연해짐
- 결합도가 낮은 객체끼리는 부품을 쉽게 갈아끼울 수 있음
@Target()
- ElementType.TYPE
- public enum ElementType {
/** Class, interface (including annotation interface), enum, or record declaration */ TYPE,- 사용처 : 클래스 , 인터페이스 , 이넘 , 레코드
TopDown 방식(테스트 코드 인듯?)
- 프로덕션 코드 작성 전에 테스트 코드를 먼저 작성하는 것(방식?)