스프링 핵심은 무엇인가
1. 스프링은 프레임워크이다.
FrameWork
Frame / work
틀안에서 / 동작한다.
2. 스프링은 오픈 소스이다.
오픈 소스 : 소스 코드 공개
즉 내부를 뜯어 고칠 수 있다.
3. 스프링은 IOC컨테이너를 가진다. (제어의 역전)
주도권이 스프링에 있다는 것이다.
- class : 설계도
- object : 실체화가 가능한 것
- instance : 실체화 된 것
내가 직접 object를 new해서 heap공간에 올리게 된다면?
ex ) 의자 S = new 의자();
- new 의자() : 의자 클래스의 새로운 인스턴스를 만들고(실체화), 이 인스턴스에 대한 참조를 변수 S에 할당
- 변수 S는 생성된 의자 객체를 가리키는 참조 변수, S는 실제로 메모리에서 의자 객체의 위치를 가리키는 주소를 저장
따라서 S에는 의자 객체의 주소가 포함된다.
public void make() {
의자 S = new 의자();
}
각각의 메서드 호출은 스택 프레임(stack frame) 또는 스택 메모리라고 불리는 메모리 블록에 저장된다. 이 스택 프레임에는 메서드의 지역 변수, 매개 변수, 및 기타 메서드 호출 정보가 저장된다.
S는 해당 make() 내에서 선언되었기 때문에 해당 스택 프레임 내에서만 존재하며 참조변수 주소가 관리된다.
만약 다른 메서드에서 의자를 사용하고 싶다면 아래와 같을 것이다.
public void use() {
의자 S = new 의자();
}
make()의 S use()의 S는 다른 객체이다.
만약 스프링이 없다면 같은 S를 쓰고 싶다면 넘겨 받아야 하는 방법만 쓸 수 있다.
의자라는 object, 책상이라는 object, 책꽂이라는 object를 클래스로 만들면
일반적으로 Spring Framework는 클래스를 스캔하여 그에 대한 메타 정보를 얻고, 빈(Bean)으로 IOC 컨테이너(스프링 컨테이너)에 등록되면 이 컨테이너에 의해 관리된다. 이렇게 등록된 빈은 스프링이 애플리케이션 실행 시점에 특정 메모리 영역인 heap에 인스턴스화되어 관리된다. 이 과정에서 스프링이 객체의 생명주기를 관리하고, 필요한 곳에 주입해주는 것이다.
따라서 IOC는 개발자가 아닌 스프링 프레임워크가 객체의 생성과 관리에 대한 제어를 담당한다는 의미로 사용된다.
참고) IOC와 static의 차이가 무엇일까 ?
method가 static이 아니라면 new 사용해서 새로 만든 후에
Class의 method를 호출합니다.
여기서 스프링의 IoC 개념이 무너집니다.
스프링은 객체를 new로 만들지 않습니다.
왜냐하면 객체의 생성 및 소멸에 대한 권한을 컨테이너에 넘겼기 때문입니다.
만약에 static을 사용하려면 의존되는 객체를 static 또는 new로 만들어야 합니다.
그러면 굳이 스프링을 사용할 필요가 없습니다.
스프링의 핵심 기능인 IoC를 사용하지 않는 것과 같습니다.
static으로 만들면 heap이 아닌 class 영역에 상주시켜 속도나 메모리 면에서 더 빠를 수 있습니다.
하지만 static method 안에 다른 객체를 new생성한다거나 해당 method가 호출될 때마다
객체가 새로 생성되며 그 객체 대한 생성과 소멸을 직접 관리해야 합니다.
스프링은 이런 객체 대한 생성과 소멸을 관리해주며,
싱글톤 레지스트리라는 방법을 사용하여
객체를 싱클톤과 같이 한번만 생성하기 때문에
오히려 성능이 좋을 수 있습니다.
출처:https://okky.kr/questions/291799
https://velog.io/@byeolhaha/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%88%B2-%EB%A7%8C%EB%93%A4%EA%B8%B0
4. DI
의자라는 클래스를 스캔하면 딱 한번 해당 빈(bean)을 생성하고 이후에는 이 빈을 필요한 곳에서 주입(Dependency Injection)하여 공유해서 사용할 수 있다.
필터란 무엇인가
스프링은 엄청 많은 필터를 가지고 있다.
필터는 즉 문지기 역할을 하며 특정 권한이 없다면 걸러낸다.
스프링 자체 필터 또는 내가 자체 필터를 생성해서 사용할 수 있다.
- 톰캣 필터(Tomcat Filter): 톰캣 웹 서버에서 요청과 응답을 처리하기 전후에 특정 작업을 수행하는 컴포넌트, 웹 애플리케이션의 web.xml 파일에서 정의된다.
- 스프링 인터셉터(Spring Interceptor): 스프링 MVC에서 컨트롤러에 요청이 도달하기 전과 후에 특정한 작업을 수행하는 기능, 주로 로깅, 보안 검사, 권한 검사 등의 작업을 수행한다. 스프링 인터셉터는 스프링 컨텍스트에서 정의되며, @Interceptor 어노테이션 또는 XML 설정을 통해 등록된다.
전에 정리해둔 필터 내용 참고 : https://young-s-note.tistory.com/100
어노테이션은 무엇인가
어노테이션은 컴파일러가 체크하는 주석이다.
Animal이란 클래스에 run메소드가 있다. Dog라는 클래스가 Animal을 상속하면 run메소드를 재정의할 수 있다. 이 때 이 메소드에 @Override를 붙인다. Dog를 컴파일면 이 오버라이드 어노테이션을 보고 Animal에 해당 메소드가 실제로 있는지 체크한다. 만약 없다면 컴파일 체킹 시에 에러가 난다.
스프링에서는 어노테이션들을 통해 주로 객체 생성을 한다. 이 어노테이션들은 약속이 정의되어 있다.
- @Component : 클래스 메모리에 로딩
- @Autowired : 로딩된 객체를 해당 변수에 집어넣어라
앞서 IOC의 설명과 연결지어 보겠다.
@Component
Class A {
}
스프링이 A클래스를 스캔해서(읽어서) 그에 대한 메타 정보를 얻고, 빈(Bean)으로 등록하여 heap메모리 공간에 A라는 클래스를 로드한다.
만약 클래스 B에서 A객체를 사용하고 싶다면
A a = new A();를 하는 것이 아니라 선언만 한 채 @Autowired를 붙인다.
@Component
Class B {
@Autowired
A a;
}
리플랙션 : 스프링이 해당 클래스를 스캔할 때 이 클래스 내의 자바 클래스의 구조, 메서드, 필드, 어노테이션 등을 분석하고 있다면 무엇을 할 지 동작을 설정하는 기법
런타임시 분석한다.
*런타임 : 런타임(runtime)은 프로그램이 실행되는 동안의 시간을 의미
현재 클래스 B에는 @Autowired와 같은 어노테이션을 사용하여 의존성을 주입할 A 객체를 선언하고있다.
이 리플랙션을 통해 B 클래스를 로딩하고 있는 동안에 A 클래스를 스캔하여 해당 객체와 동일한 타입의 빈으로 등록된 객체를 찾는다. 그리고 해당 객체를 B 클래스의 a 변수에 주입한다. 따라서 B 클래스가 스프링에 의해 관리되는 빈이고 A 클래스도 스프링에 의해 관리되는 빈이라면, B 객체가 생성될 때 A 객체가 자동으로 주입된다.
만약 A가 없다면 null이 주입되고 NullPointerException 등의 예외를 발생시킬 수 있다.
메세지 컨버터(Message Converter)가 무엇인가
중간 언어 : 한국어와 영어와 같이 서로 다른 언어를 바로 번역하는 것이 어려운 경우에 사용되는 언어
이는 한국어와 영어를 모두 이해할 수 있는 중간 형태의 언어로, 양쪽 언어 간의 번역을 도와준다. 중간 언어의 예로는 예전에는 XML이 주로 사용되었지만, 현재는 JSON이 많이 사용된다. JSON은 간단하고 사용하기 쉬운 형식으로, 다양한 언어와 플랫폼 간에 데이터를 교환하는 데 많이 활용된다.
자바 오브젝트를 JSON으로 변환하여 다른 시스템으로 전달하고, 해당 시스템에서는 JSON을 파싱하여 데이터를 이해한다.
예를 들어, 자바로 작성된 서버에서 데이터를 처리한 후 JSON 형식으로 응답하면, 클라이언트는 해당 JSON을 받아서 자바스크립트나 다른 언어로 데이터를 처리할 수 있다.
다른 예를 들자면 자바 오브젝트를 JSON으로 변환하여 파이썬으로 전송하면, 파이썬 시스템에서는 해당 JSON을 파싱하여 파이썬 객체로 변환한다.
메시지 컨버터 : 자바 객체와 JSON 데이터를 변환하는 역할
스프링 프레임워크에서는 기본적으로 메시지 컨버터를 제공하여 자바 객체를 JSON으로 변환하고, 반대로 JSON을 자바 객체로 변환하는 작업을 수행한다. 이를 통해 서로 다른 시스템 간에 데이터를 주고받을 때 편리하게 사용할 수 있다.
스프링은 BufferedReader와 BufferedWriter를 제공해 데이터를 효율적으로 읽고 쓸 수 있다.
데이터가 통신할 때 전기선을 통해서 이동하며, 보통은 0과 1의 비트로 이루어져 있다. 이러한 비트 단위의 통신은 사람이 이해하기 어렵기 때문에 문자로 변환하여 통신한다. 문자는 8비트, 즉 1바이트로 표현되며 통신의 최소단위이다. 이를 이용하여 256가지의 문자를 표현할 수 있다.
그러나 한글과 같은 문자는 최소 16비트가 필요하다. 이런 경우 자바에서는 데이터를 읽을 때 InputStream을 사용하여 바이트 단위로 읽는다. InputStream을 InputStreamReader로 감싸면 바이트를 문자로 변환하여 문자 하나를 읽을 수 있다. 또한 InputStreamReader는 한 문자뿐만 아니라 배열로 여러 문자를 받을 수 있다. 다만 배열의 크기가 정해져있다.
이 단점을 극복하기위해 데이터를 읽을 때 BufferedReader로 사용하면 가변길이의 문자배열도 가능하다. JSP에서는 request.getReader() 함수를 쓰는데 이 함수가 BufferedReader역할을한다.
BufferedWriter는 데이터를 출력할 때 데이터를 버퍼에 임시로 저장한 후, 버퍼가 가득 차거나 flush() 메서드가 호출될 때까지 기다린다. 그리고 한 번에 버퍼에 있는 데이터를 출력한다.이렇게 함으로써 매번 데이터를 출력할 때마다 입출력 작업이 발생하는 것을 방지하고, 여러 개의 작은 데이터를 연속적으로 출력하는 경우에도 효율적으로 처리할 수 있다. 전송 단위가 문자열로 되어 있고 가변 길이의 데이터를 쓰기에 적합한데, 데이터의 길이가 일정하지 않아도 BufferedWriter를 사용하여 데이터를 출력할 수 있다
PrintWriter는 BufferedWriter와 유사하게 작동하지만, 추가적으로 Print() 및 Println()과 같은 텍스트 출력 메서드를 제공한다. JSP에서는 out 내장 객체가 있는데 BufferedWriter와 유사한 기능을 제공한다.
스프링에서는 @ResponseBody 어노테이션을 사용하여 응답 데이터를 출력할 수 있다. 이는 내부적으로 BufferedWriter를 활용한다. 데이터를 받을 때는 @RequestBody 어노테이션을 사용하여 BufferedReader를 사용할 수 있다. 이를 통해 스프링에서는 효율적인 데이터 통신을 구현할 수 있다.
참고 자료 출처 :
https://velog.io/@byeolhaha/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%88%B2-%EB%A7%8C%EB%93%A4%EA%B8%B0
'Spring Boot' 카테고리의 다른 글
스프링부트 Controller에 관한 개념 (0) | 2024.03.23 |
---|---|
yml 파일 설정 및 이해 (0) | 2024.03.23 |