1. Spring이란?
- Java 플랫폼을 위한 오픈소스 애플리케이션 프레임워크 중 하나 (자바 기반의 가볍고 유지 보수가 간편한 장점)
2. Spring의 특징
- IOC(Inversion Of Control, 제어의 역전) - 개발자가 직접 제어하는 것이 아닌 다른 주체(Spring)에게 제어권을 위임
- DI(Dependency Injection, 의존성 주입) - 객체를 개발자가 직접 생성하는 것이 아니라 외부(Spring IOC container)에서 생성해서 사용하려는 주체에 객체를 주입시켜주는 방식 (생성자, 필드, setter 주입이 있음)
=> 객체 간의 종속성 감소, 코드 단순화, 코드의 재사용성과 유지보수성을 높여줌
=> 한 클래스를 수정하였을 때, 다른 클래스도 수정할 필요가 없어짐
- AOP(Aspect Oriented Programming, 관점 지향 프로그래밍) = 공통 기능을 분리(Aspect)한 뒤 모듈화하여 지정 시점에 해당 로직을 재사용하는 프로그래밍 방식
- 영속성(Persistence)과 관련된 다양한 서비스를 지원함
※ 영속성(Persistence) = 데이터를 생성한 프로그램의 실행이 종료되더라도 사라지지 않는 데이터의 특성
- 자체적으로 Apache Tomcat과 같은 웹 어플리케이션 서버가 내장되어 있어 자바 웹 어플리케이션을 구동할 수 있음
※ 스프링 빈(Bean) = Spring IOC Container가 관리하는 자바 객체
3. Spring의 작동 과정
- Client에서 Request 요청
- 해당 Request를 DispatcherServlet이 받아 HandlerMapping을 사용해 해당 요청을 매핑한 Controller 탐색 후 적합한 Controller에 Request 전달
- Controller에서 비즈니스 로직 처리 후 결과값(Model)과 결과값을 출력할 View 이름을 DispatcherServlet에 반환
- DispatcherServlet이 ViewResolver로 View 이름을 전달
- ViewResolver가 해당 이름을 가진 View 탐색 후 DispatcherServlet에 반환
- DispatcherServlet이 View에 Model을 전달
- View가 전달받은 Model를 토대로 렌더링
- 렌더링 된 View를 DispatcherServlet이 Client로 전달
※ Vue.js나 React.js처럼 사이드 프레임워크로 프론트를 구성하는 경우에는 ViewResolver 사용 없이 DispatcherServlet이 Model만 Client로 전달
※ Servlet = 웹 통신에서 Client의 요청을 동적으로 처리하고 요청에 대한 응답을 Client에 전송하는 자바 객체
※ DispatcherServlet = HTTP로 들어오는 모든 요청을 가장 먼저 받아 적합한 컨트롤러에 전달해주고 그 결과값을 받아서 View에 전달하여 적절한 응답을 생성할 수 있도록 흐름을 제어하는 프론트 컨트롤러
=> 기존에는 모든 요청에 대한 각각의 서블릿을 web.xml에 모두 등록해야 했지만 DispatcherServlet이 모든 요청을 받음으로써 작업을 편리하게 진행할 수 있게 되었음
※ HandlerMapping = DispatcherServlet으로부터 받은 요청을 처리할 컨트롤러를 매핑해주는 객체
※ ViewResolver = DispatcherServlet으로부터 받은 View 정보를 토대로 실제 작업을 처리할 View를 탐색해주는 역할 (JSP나 서블릿 사용 시)
4. MyBatis, JPA 차이
MyBatis
- SQL Mapper => 객체와 작성한 SQL문의 필드를 매핑하여 데이터를 객체화
- DB에 종속적
- SQL을 직접 작성하여 수행 결과를 객체와 매핑 => 복잡한 쿼리문 작성 가능
- CRUD 메소드를 직접 다 구현해야 함
- 쿼리문을 XML로 분리
JPA(Java Persistence API)
- ORM(Object Relational Mapping) => 객체와 DB Table을 매핑하여 객체화
- DB에 종속적 X => DB 데이터 변경시 객체만 변경하면 됨 (객체 중심 프로그래밍 가능)
- 쿼리 메소드를 통해 기본적인 CRUD 메소드 제공
- 다중 조인과 같은 복잡한 쿼리는 어려움
- 코드가 간단함
5. Service 인터페이스와 ServiceImpl 클래스 구분 이유
- 인터페이스와 구현체를 분리함으로써 구현체를 독립적으로 두고, 구현체 클래스를 변경하거나 확장해도 이를 사용하는 클라이언트의 코드에 영향을 주지 않도록 하기 위해서
- 이를 통해 객체 간의 결합도를 낮추고 코드의 가독성 및 확장성을 지키며 유지보수가 간편해짐
6. MVC 패턴
- 애플리케이션의 구성 요소를 Model, View, Controller로 구분한 디자인 패턴
- Model = 데이터 객체 자체 + 데이터 조작 및 처리
- View = 사용자에게 보여지는 화면 (UI)
- Controller = View와 Model 사이의 중개자 역할 (요청에 따라 모델 객체와 뷰를 변화시킴)
- 일종의 식당의 요리사(Model), 매니저(Controller), 웨이터(View)와 비슷
- 장점 = 비교적 간단한 패턴이라 구조파악과 확장이 용이함, 비즈니스 로직과 UI로직을 분리하여 유지보수를 독립적으로 수행할 수 있음
- 단점 = View와 Model 사이의 의존성이 큼 => 애플리케이션이 커지면 컨트롤러의 코드량이 증가하여 복잡해지기 때문에 유지보수가 어려움
7. 빈(Bean) 등록 방법
- xml 파일로 따로 관리
- java로 config 파일을 따로 만들어 @Configuration, @ComponentScan
- @SpringBootApplication (스프링 부트에서만) => 편리하게 자동 등록
8. 의존성 주입 (DI, Dependency Injection)
- 객체를 내부(개발자)에서가 직접 생성하는 것이 아니라 외부(Spring IOC container)에서 런타임 시점에 생성해서 사용하려는 주체에 주입시켜주는 방식
- 의존성(Dependency) = 코드에서 두 모듈간의 연결 (의존대상 B가 변하면, 그것이 A에 영향을 미치는 것)
생성자 주입
- 가장 권장되는 의존성 주입 방식
- private final + 클래스 생성자로 의존성 주입
장점
- 순환 참조 방지
- 테스트 용이
- final 선언 가능으로 불변성 보장
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
private final TokenProvider tokenProvider;
@AutoWired // 생성자가 1개이면 @AutoWired 생략 가능
public SecurityConfig(TokenProvider tokenProvider) {
this.tokenProvider = tokenProvider;
}
}
필드 주입
- 필드에 @AutoWired를 입력해줌으로써 의존성 주입
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@AutoWired
private TokenProvider tokenProvider;
}
setter 주입
- setXX 메소드를 정의하여 의존성 주입
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
private TokenProvider tokenProvider;
@AutoWired
public void setTokenProvider(TokenProvider tokenProvider) {
this.tokenProvider = tokenProvider;
}
}
9. 스레드(Thread) 사용 방법
Thread 클래스 확장
- Thread 클래스(추상 클래스)를 확장한 상태에서 run() 메소드를 오버라이드하여 실행할 작업을 정의
- start()로 스레드 실행
- 단일 상속만 가능
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running");
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // 새 스레드 실행
}
}
Runnable 인터페이스 구현
- Runnable 인터페이스를 구현한 상태에서 run() 메소드를 오버라이드하여 실행할 작업을 정의
- Runnable 객체를 Thread 객체에 전달하여 start()로 스레드 실행
- Thread 클래스와 분리되어 있으므로 여러 스레드에서 동일한 작업을 공유(다중 상속)할 수 있어 권장되는 방식
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Runnable thread is running");
}
}
public class Main {
public static void main(String[] args) {
MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start(); // 새 스레드 실행
}
}
'면접 대비' 카테고리의 다른 글
CS 관련 면접 질문 정리 (DB) (0) | 2023.01.30 |
---|---|
CS 관련 면접 질문 정리 (OS) (0) | 2023.01.16 |
CS 관련 면접 질문 정리 (Java) (0) | 2023.01.16 |
CS 관련 면접 질문 정리 (네트워크) (0) | 2023.01.04 |
댓글