스프링은 프레임워크이다
Frame(틀)work(동작하다)
개발에 필요한 기본적인 틀을 제공하여 사용다로 하여금 구조 디자인의 수고와 노력을 덜게 해준다.
스프링은 오픈소스이다
스프링의 내부 구도와 원리를 볼 수 있으며, 필요에 따라 직접 수정하여 발전시킬수 있다.
스프링은 IoC컨테이너를 가진다
Inversion of Control의 약자로, 제어의 역전이라는 뜻이다.
object → 실체화가 가능한 개념
class → 실체화가 가능한 개념에 대한 설계도
instance → 개념이 현실로 실체화 된 것
개념적으로 오브젝트의 구조를 코딩한 뒤, 연산자 new를 사용하여 메모리의 heap영역에 띄움으로써 인스턴스화 한다. 메모리에 위치한 인스턴스의 멤버는 인스턴스의 소멸과 함께 존재가 사라진다.
유효범위가 다른 메소드에서 필요로 하여 접근해도 값을 가져올 수 없다. 만약 연산자를 사용하여 새로운 인스턴스를 띄운다 하더라도, 생성된 인스턴스와 소멸되었던 인스턴스는 일치한다고 말할 수 없다. 이는 오브젝트나 인스턴스의 멤버를 용이하게 사용하기 어렵게 만든다.
스프링은 애플리케이션 시작 시, 사용자가 디자인 해둔 오브젝트들을 직접 heap 메모리에 할당한다. 이를 IoC라 부른다. 오브젝트에 대한 제어의 주체가 스프링 애플리케이션이 된것이다.
스프링은 DI를 지원한다
Dependency injection의 약자로, 의존성 주입이라는 뜻이다.
IoC 과정을 통해 생성된 객체들은 애플리케이션 내에 선언된 모든 메소드에서 사용할 수 있다. 당연하게도 컨테이너에 등록되어있는 인스턴스는 유일하니, 이 인스턴스 멤버의 동일성과 유일성을 보장할 수 있다. 이를 Singleton디자인 패턴이라 부른다.
이렇게 다른 범위에서 값을 가져와 사용하는것을 DI라고 한다.
스프링은 무수한 필터를 가지고 있다
무수히 많은 요청과 응답을 처리하는 서버에게 요청의 관리와 권한 부여는 매우 중요하다. 서버에 대한 공격을 내재한 요청은 아닌지, 정당한 형태를 가지고 보내진 요청인지, 요청이 접근하려는 곳에 대해 접근권한은 있는지 종합적으로 관리하는 기능이 필요하다.
톰캣과 스프링이 자체적으로 가지고있는 필터가 이러한 역할을 한다. 톰캣에 장착된 필터는 web.xml이며, 스프링 컨테이너에 장착된 필터는 인터셉터이다.
스프링은 무수한 어노테이션을 가지고있다
컴파일러가 무시하는 메모나 토막글은 주석이라 부른다.
컴파일러에게 힌트를 주어 체크하도록 만들어주는 정보를 어노테이션이라 부른다.
그 예로, @Override 어노테이션은 컴파일러가 오버라이딩 된 메소드를 만났을 시, 부모 클래스가 이를 가지고있는지 확인하도록 한다. 만약 없다면, 컴파일러가 오류로 판단한다.
스프링 프레임워크는 어노테이션을 이용해 주로 객체를 관리한다.
@Component 어노테이션이 붙어있는 클래스는 메모리에 로딩시키고,
@Autowired 어노테이션이 붙어있는 클래스는 로딩된 객체를 해당 변수에 주입시키고,
@Bean 어노테이션이 붙어있는 클래스는 IoC 컨테이너에서 관리하도록 등록시킨다.
스프링 프레임워크에서 어노테이션과 같이 생각되는 개념은 Reflection이다. 어노테이션이 정보를 주었다면, 리플렉션은 런타임 시 인스턴스와 객체를 분석하여 주입해주는 역할을 한다.
스프링은 MessageConverter를 가지고있다(기본값은 현재 JSON)
수백개의 언어를 가지고 있는 세계에서 만국 공용어인 영어가 존재하듯이, 클라이언트와 서버 또는 서버와 서버 사이에서도 이러한 공통된 소통의 기준이 필요하다. 많은 사용자의 데이터교환에 있어 공용되는 데이터 구조는 JSON이다. 자바 오브젝트를 누군가에게 전송하거나 전송 받을때 JSON객체로 바꾸어주는 변환기를 MessageConverter라 한다.
스프링은 BufferedReader와 BufferedWriter를 쉽게 사용할 수 있다
데이터는 물리적으로 케이블에서 전류를 이용해 전송된다. 통신의 근간을 이룬 영어권을 기준으로, bit단위로 전송되는 데이터로 문자를 조합해내기 위해선 최소 256가지의 경우의 수가 필요하다. 이는 8비트, 1바이트로 이루어지는 아스키코드를 만들어낸 이유이자 기준이 되었다. 하지만 이에 비해 한글 문자의 조합수는 16비트, 2바이트의 코드가 필요하다. 각 나라마다 문자를 조합하는 방법이 서로 달라지자 이 또한 기준이 필요해지게 되었다. 유니코드에서 3바이트의 기준을 담고있는 UTF-8 통신의 기준을 마련하여 제공하는 계기가 되었다.
이렇게 문자를 구성하는 단위가 커질수록, InputStream의 자원 낭비가 심해지게되었다. 최대 받을 수 있는 길이의 문자열을 정해두고, 그 문자열의 길이를 기준으로 통신을 하는 방식이었다. 20자 크기의 스트림을 받는데, 2문자 크기의 데이터가 전송되면 나머지 18자는 낭비가 되는것이다.
이를 해결하기 위해 통신할때엔 데이터를 BufferedReader로 감싼다. 가변길이의 데이터로 통신을 할 수 있는것이다.
스프링에선 @RequestBody 어노테이션을 통해 BufferedReader를, @ResponseBody 어노테이션을 통해 BufferedWriter를 구현할 수 있다.