프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해서 로직을 구성하는 프로그래밍 방법입니다.
코드 재사용이 용이하다.
다른 사람이 만든 클래스를 가져와 사용이 가능하다.
유지보수가 쉽다.
해당되는 부분만 수정하면 되기 때문이다.
대형 프로젝트에 적합하다.
클래스 단위로 모듈화 시켜서 개발이 가능하다.
SPR(Sing Responsibility Principle)
단일 책임 원칙 클래스는 단 하나의 책임을 가져야 하며 클래스를 변경하는 이유는 단 하나의 이유이어야 한다.
OCP(Open- Closed Principle): 개방-폐쇄 원칙 확장에는 열려있어야 하고 변경에는 닫혀있어야 한다.
LSP(Liskov Substitution Principle): 리스ㅡ코프 치환 원칙 상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
ISP(Interface Segregation Principle): 인터페이스 분리 원칙 인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 한다.
DIP(Dependency Inversion Prinsiple): 의존 역전 원칙 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안된다.
추상화 : 불필요한 정보는 숨기고 중요한 정보만을 표현함으로써 공통의 속성이나 기능을 묶어 이름을 붙이는 것
캡슐화 : 기능과 특성의 모음을 "클래스"라는 "캡슐"에 넣어서 분류하는 것
구현방법: interface 와 implements를 따로 두어 interface에서만 접근 가능하도록 하게 한다.
상속 : 상속은 부모 클래스의 속성과 기능을 그대로 이어받아 사용할 수 있게 한다.
기능의 일부분을 변경해야 할 경우 상속받은 클래스에서 해당 기능만 다시 수정하여 사용할 수 있게 하는 것이다. 다중상속 x
다형성 : 하나의 변수명, 함수명 등이 상황에 따라 다른 의미로 해석될 수 있는 것.
즉, 오버라이딩(Overriding), 오버로딩(Overloading)이 가능하다는 얘기다.
-오버라이딩 : 부모클래스의 메서드와 같은 이름, 매개변수를 재정의 하는 것
-오버로딩 : 같은 이름의 함수를 여러 개 정의하고, 매개변수의 타입과 개수를 다르게 하여 매개변수에 따라 다르게 호출할 수 있게 하는 것
자바 컴파일러가 .java 파일을 컴파일하면 .class라는 자바 바이트코드로 변환시켜준다. 이 때 바이트 코드가 기계어가 아니기 때문에 운영체제에서 바로 실행하지 못하는 데, 운영체제가 이해할 수 있도록 해석해주는 것이 JVM이다.
컴파일 -> 바이트 코드 -> 기계어 이런 식으로 중간에 바이트 코드 과정이 있기 때문에 속도와 메모리에서 단점이 될 수 있다.
JVM을 사용하면 운영체제에 상관없이 같은 코드를 사용할 수 있다.
DI는 의존성 주입의 약자로, 객체들 간의 의존성을 줄이기 위해 사용되는 스프링의 IOC 컨테이너의 구체적 구현 방식을 말한다.
필드 주입, setter주입, 생성자 주입 3가지가 있다.
개발코드 부분에서 객체를 생성하는 것이 아니라, 데이터 주입만 담당하는 별도의 공간에서 객체를 생성하고, 데이터 간의 의존성을 주입해 개발코드에서 가져다 쓰면서 의존성을 줄인다.
IOC는 제어의 역전으로 인스턴스의 생성부터 소멸까지 개발자가 아닌 컨테이너가 대신 관리해주는 것을 말한다.(프레임 워크의 개념)
IOC 컨테이너는 DI를 통해서 주입시킨다.
인스턴스의 생성의 제어를 서블릿과 같은 bean을 관리해주는 컨테이너가 관리한다.
spring IoC 컨테이너가 관리하는 자바 객체를 빈(bean)이라는 용어로 부른다. 우리가 new 연산자로 어떤 객체를 생성했을 때 그 객체는 빈이 아니다.
즉, 스프링 컨테이너가 생성한 객체들을 'bean'이라고 한다.
실행되는 시점에서 차이가 있다. 필터는 dipatcherServlet으로 요청이 가기 전에 실행되고 인터셉터는 Controller로 요청이 가기전에 실행된다.
따라서 컨트롤러에 들어가기 전 작업을 처리하기 위해 사용하는 공통점이 있지만, 호출되는 시점에서 차이가 존재한다.
객체란, 소프트웨어 세계에 구현할 대상이다.
클래스의 인스턴스 라고도 부른다. OOP 관점에서 클래스의 타입으로 선언되었을 때 객체라고 부른다.
객체는 현실 세계에 가깝고, 인스턴스는 소프트웨어 세계에 가깝다.
연관되어 있는 변수와 메서드의 집합
클래스란, 객체를 만들어 내기 위한 설계도 혹은 틀이라고 할 수 있다.
객체를 소프트웨어에 실체화 하면 그 것을 인스턴스 라고 부른다.
OOP의 관점에서 객체가 메모리에 할당되어 실제 사용될 때 인스턴스 라고 부른다.
객체는 클래스의 인스턴스이다.
//클래스
public class Animal{
...
}
//객체와 인스턴스
public class Main{
public static void main(String[] args)
{
Animal cat, dog; //객체
//인스턴스화
cat = new Animall();
dog = new Animall();
}
}
클래스로부터 객체를 만드는 과정을 클래스의 인스턴스화라고 한다.
어떤 클래스로부터 만들어진 객체를 그 클래스의 인스턴스라고 한다.
String은 불별한다는 특징을 가지고 있어 수정하지 못한다. 따라서 새로운 String 인스턴스가 생성되고 전에 있던 String은 가비지 컬렉터에 의해서 사라지게 된다. 그래서 좋은 성능을 기대하기 힘들다.
StringBuffer는 동기화 키워드를 지원하여 멀티쓰레드 환경에서 안전하다는 점(thread-safe)이다. 참고로 String도 불변성을 가지기 때문에 마찬가지로 멀티 스레드 환경에서 안정성(thread-safe)을 갖고 있다.
반대로 StringBulider는 동기화를 지원하지 않기 때문에 멀티쓰레드 환경에서 사용하는 것은 적합하지 않다. 동기화를 고려하지 않는 만큼 단일 쓰레드에서의 성능은 SpringBuffer보다 뛰어나다.
운영체제로부터 시스템 자원을 할당받는 작업의 단위
하나의 프로세스는 크게 코드영역, 데이터영역, 스택영역, 힙영역 4가지로 이루어져 있다.
장점: 안정성이 높다. (독립된 구조라서)
단점: 여러 프로세스를 왔다갔다 하는 컨텍스트 스위칭으로 인한 성능저하
장점: 응답시간 단축, 자원소모 감소
단점: 미묘한 시간차나 변수 공유함으로써 오류가 발생 가능하다.
MVC 패턴은 Model, View, Controller 이 3가지로 나뉘어 역할을 분할하여 처리한다.
역할을 나누어 처리하기 때문에 서로의 결합도가 낮아져 좋은 코드가 되며 유지보수도 하기 편해진다.
Entity에는 가겁적 setter를 사용하지 말아야 한다.
-Entity가 영속성이 유지되는 도중 수정되면 그 값은 DB에 그대로 반영된다.
그런데 setter를 열어두고 값을 변경하는 경우에는 변경 포인트가 많아 유지보수가 어려워질 수 있다.
모든 연관관계는 지연로딩으로 설정한다.
-즉시로딩을 사용할 경우, 어떤 SQL이 나갈지 추적하기가 어렵다.
컬렉션은 필드에서 바로 초기화한다.
Entity는 최대한 순수하게 유지해야 한다.
순환참조를 예방할 수 있다.
-JPA로 개발할 때, 양방향 참조를 사용했다면 순환참조를 조심해야 한다.
엔티티 내부 구현을 캡슐화 할 수 있다.
DB Layer와 View Layer 사이의 역할을 분리 하기 위해서다.
Lazy로딩에 의해서 한 번에 모든 정보를 가져오지 못해서 발생하는 문제이다. 이는 페치조인을 사용하여 해결할 수 있다.
SQL 한 번으로 100명의 회원을 조회하였는데, 한 번 SQL을 실행해서 조회된 결과 수 만큼 N번 SQL을 추가로 실행한다고 하여 N+1 문제라 한다.
각 회원마다 주문한 상품을 추가로 조회하기 위해 100번의 SQL을 추가로 실행하는 상황을 말한다.
필드 인젝션은 점차 테스트 코드의 중요성이 부각됨에 따라서 필드의 객체를 수정할 수 없는 필드 주입은 사용하지 않는 것이 좋다. 또한, 필드 주입은 반드시 DI 프레임워크가 존재해야 하므로 반드시 사용을 지양해야 한다.
생성자 인젝션은 생성자로 객체를 생성하는 시점에 필요한 빈을 주입한다. 그러므로 순환참조를 해결할 수 있다. 필드를 final로 선언 가능하다. DI 컨테이너를 사용하지 않고도 테스르를 진행 할 수 있다.
함수형 프로그래밍은 명령형이 아닌 선언적 방식으로 구현되며 흐름 제어를 명시적으로 기술하지 않고 프로그램 로직이 표현된다는 것을 의미한다.
람다는 함수의 구조로 되어있고 -> 와 같이 화살표 형태의 기호를 이용해 매개변수를 함수 바디로 전달하는 형태이다.
List : 순서가 있는 데이터의 집합으로 데이터의 중복을 허용한다.
Set : 순서를 유지하지 않는 데이터의 집합으로 데이터의 중복을 허용하지 않는다.
Map : 키, 값으로 이루어진 데이터의 집합으로, 순서는 유지되지 않으며 키의 중복을 허용하지 않으나 값의 중복은 허용한다.
ORM이란 객체와 DB테이블이 매핑을 이루는 것을 말한다. 즉, 객체가 테이블이 되도록 매핑 시켜주는 것을 말한다.
ORM을 이용하면 SQL Query가 아닌 직관적인 코드로서 데이터를 조작할 수 있다
JPA란 자바 ORM 기술에 대한 API 표준 명세를 의미한다.
Hibernate는 JPA라는 명세의 구현체이다.
장점
-생산성 : SQL의 반복작업이 없어진다.
-유지보수 : 테이블 컬럼 한개가 바뀌면 Mybatis에서는 관련 DAO의 파라미터, 결과 SQL등을 모두 확인하여 수정해주어야 한다. JPA는 대신 해준다.
단점
-성능 : 직접 SQL을 호출하는 것 보다 성능이 떨어질 수 있다.
-세밀함 : 복잡한 통계 분석 쿼리를 메서드 호출로 처리하기 힘들다.
(이러한 문제를 보완하기 위해 JPA에서 JPQL을 지원한다.)
클라이언트로부터 요청이 들어오면 dispatcherServclet이 가장 먼저 받는다.
HandlerMapping이 요청 URL과 매핑되는 Controller 검색 후 리턴
HandlerAdapter에서 알맞은 controller 처리 요청
ViewResolver에서 controller가 리턴한 view 검색 후 view를 클라이언트로 보냄
관점 지향 프로그래밍, 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화 하겠다는 것이다.
스프링 빈에만 AOP 적용 가능
프록시는 타겟을 감싸서 타겟의 요청을 대신 받아주는 랩핑 오브젝트이다.
프록시의 단어 자체로는 '대리인'이라는 의미를 내포하고 있다. 스프링 AOP에서의 프록시란 말그대로 대리하여 업무를 처리, 함수 호출자는 주요 업무가 아닌 보조 업무를 프록시에 맡기고, 프록시는 내부적으로 이러한 보조 업무를 처리
스프링 기반의 어플리케이션의 보안을 담당하는 프레임워크이다.
세션-쿠키 방식으로 인증한다.
OAuth(OpenID Authenication)란, 타사의 사이트에 대한 접근 권한을 얻고 그 권한을 이용하여 개발할 수 있도록 도와주는 프레임워크다. 구글, 카카오, 네이버 등과 같은 사이트에서 로그인을 하면 직접 구현한 사이트에서도 로그인 인증을 받을 수 있도록 하는 구조다.
OAuth2 로그인을 사용한다면 'UsernamePasswordAuthenticationFilter'대신 'OAuth2LoginAuthenticationFilter'가 호출되게 해야한다.
oauth는 세션대신 토큰을 사용하여 인증 진행(토큰을 또 JWT토큰으로 바꿔서 많이 사용한다.)
영속성 컨텍스트는 엔티티를 영구 저장하는 환경이라는 뜻이다. EntityManager는 영속성 컨텍스트에 Entity를 보관하고 관리
영속성 컨텍스트의 장점
-1차캐시: 1차캐시에서 데이터를 먼저 찾고 없으면 DB에서 차즌ㄴ다.
-동일성 보장
-쓰기 지연: 트랜젝션을 커밋하기 직전까지 쿼리를 날리지 않고 영속성 컨텍스트에 보관한다.
-변경 감지: 스냅샷을 이용하여 영속성 컨텍스트에 저장된 엔티티는 변경이 일어나면 자동으로 데이터베이스 에서 수정된다.
-지연 로딩: 실제 객체 대신 프록시 객체를 로딩해두고 해당 객체를 실제 사용할 때 영속성 컨텍스트를 통해 불러오는 방법