ResourceLoader
리소스를 읽어오는 기능을 제공하는 인터페이스
- 파일 시스템에서 읽어오기
- 클래스패스에서 읽어오기
- URL로 읽어오기
- 상대/절대 경로로 읽어오기
---------------------------
Resource 추상화
java.net.URL을 추상화 한 것 -> springcore.io.resource로 해당 클래스를 감싸서 실제 low-level에 있는 resource에 접근하는 기능을 만든것이다.
이유 -> 기존 java.net.URL은 클래스패스로 resource를 가져오는 기능과 ServletContext기준으로 resource를 가져오는 기능이 없었다. resource를 가져오는 방법을 하나로 통일시킨것.
구현체 - UrlResource, classpathResource, FileSystemResource, ServletContextResource
ServletContextResource - 웹 애플리케이션 루트에서 상대 경로로 리소스를 찾는다.
ApplicationContext의 타입에 따라 리소스 타입이 달라지지만 리소스 타입을 강제할 수도 있다.
- classpath: <- 클래스 패스 기준으로 온다는것을 명시
- file: <- 파일 경로로 온다는것을 명시
스프링 부트 기반의 애플리케이션에서 리소스 타입을 명시하지 않으면 ServletContextResource기준으로 처리가 된다. -> 보통 claspath 기준으로 많은 리소스를 사용하므로 가능하다면 classpath 로 명시하도록 하자
Validation 추상화
애플리케이션에서 사용하는 객체 검증 인터페이스
어디에서든 (웹 ,서비스, 데이터 계층 구분 없이)사용할 수 있다.
BeanValidation 1.0, 1.1, 2.0까지 지원 - BeanValidation이 제공하는 여러 Validation용 annotation들을 사용해 객체의 데이터를 검증할 수 있다.
BeanValidation - 여러 annotation을 사용하여 Bean의 데이터를 검증할 수 있다.
validator
- 스프링이 제공하는 validator에는 두가지 메소드가 있다.
-- supports
--- 검증해야하는 인스턴스의 클래스가 해당 Validator가 지원하는, 검증할 수 있는 Class인지 확인하는 메소드
-- validate
--- 실질적으로 검증작업이 이루어 지는 메소드
-------------------------
데이터 바인딩 추상화 PropertyEditor interface
스프링 3.0이전까지 사용하던 인터페이스
데이터 바인딩 -> 프로퍼티의 값을 타겟 객체에 설정하는 것 -> 사용자가 입력한 값을 어플리케이션 도메인에 할당하는 것
바인딩이 필요한 이유 -> 주로 스트링 값으로 값이 넘어오는데 해당 문자열을 객체마다 가지고 있는 다양한 프로퍼티 타입으로 변환해줘야 하기 때문이다.
에디터를 작성할 시에 implementPropertyEditor를 구현하게 되면 직접 구현해야 하는 메소드들이 너무 많아 힘들다.
extends PropertyEditorSupport를 상속하면 필요한 것만 구현할 수 있게 되어 편리한다.
작성한 Editor내부에서 사용하는 getValue와 setValue에서 등장하는 value는 PropertyEditor가 가지고 있는 값이다. 이 값은 서로 다른 스레드에 공유가 되기 때문에 stateFull하다. Thread-Safe하지 않다. -> PropertyEditor는 가능한한 Bean으로 등록해서는 안된다. -> 한 thread안에서만 유효한 thread scope Bean으로 만들어서 사용할 수도 있다. -> 하지만 Bean으로 등록 자체를 안하는것을 추천
그럼 어떻게 사용하죠? -> 컨트롤러에 @InitBinder를 사용해서 해당 컨트롤러에서 사용할 Binder를 등록하는 방법
Spring 3.0에서부터 등장한 Converter, Formatter
PropertyEditor가 가지는 단점들 때문에 Converter가 생겼다 ( Thread-Safe하지않다, Object-String간의 변환만 가능하다.)
Converter
- Source타입에서 Target타입으로 변환할 수 있는 일반적인 변환기.
- 상태 정보가 없다 -> 즉 Thread-Safe하다.
Formatter
- PropertyEditor를 대신한다.
- Object와 String간의 변환을 담당
- Locale에 따라 다국화 하는 기능도 제공
ConversionService
- 레지스트리에 등록 된 컨버터나 포메터들의 실제 변환 작업은 이 인터페이스를 통해 thread-safe하게 사용할 수 있다.
Formatter-Registry는 사실 Converter-Registry를 상속받고 있다.
-------------------------------
SpEL
Spring Expression Language - Spring 3.0부터 지원
객체 그래프를 조작하거나 조회하는 기능을 제공
Unified EL과 비슷하지만 그에 추가적으로 다음과 같은 기능들이 필요했기에 개발되었다.
1. 메소드 호출을 지원
2. 문자열 템플릿 기능 지원
#{} <- {} 사이의 값을 표현식으로 인식한다.
${} <- {} 사이의 값을 프로퍼티로 인식한다.
표현식은 프로퍼티를 가질 수 있지만, 프로퍼티는 표현식을 가질 수 없다.
#{${cart.data} + 1} <- 이런식으로 가능하다.
------------------------------
AOP
Aspect Oriented Programming
OOP를 더 OOP 답게 사용할 수 있도록 보완하는 수단.
흩어진 Aspect를 모듈화 하는 프로그래밍 기법
흩어진 관심사 - Crosscutting Concerns
여러 클래스에 걸쳐 나타나는 비슷한 코드들
eg) 트랜잭션, 로깅...
이러한 코드들에 변경이 일어나면 해당 코드들을 하나하나 찾아가며 수정해야한다. - 유지보수가 쉽지 않다.
각각의 Concern별로 Aspect를 사용하여 하나로 묶고 어디에 사용되어야 할지 개발자가 지정한다. -> 쉽게 말하면 "해야할 일"을 "어디에" 적용해야 하는지를 묶어서 모듈화 하는것
Aspect - 해야할 일을 하나로 묶은 모듈. Advice(해야할 일)와 Point Cut(어디에)이 들어간다.
Target - 적용할 대상
Advice -
Join Point - 끼어들 수 있는 지점들. 생성자 호출 직전, 생성자 호출한 뒤, Filed에 접근하기 전, ......
Point Cut - Join Point의 구체적인 위치
AOP 적용 방법
- 컴파일 시점
- 로드타임 시점
- 런타임 시점
스프링 AOP
Proxy 기반 AOP
스프링 Bean에만 AOP를 적용할 수 있다.
스프링 IoC와 연동하여 엔터프라이즈 애플리케이션에서 가장 흔한 문제에 대한 해결력을 제공하는 것이 목적
Proxy 패턴
클라이언트는 인터페이스타입으로 프록시 객체를 사용하게 된다.
프록시 객체는 타겟 객체를 참조하고 있다.
접근을 제어하거나 부가 기능을 추가하기 위해 사용된다.
다만 매번 프록시 클래스를 만들어야 하고, 중복 코드가 발생하게된댜.
해결방법
- 런타임에 동적으로 어떤 객체를 Proxy객체로 감싸는 방법을 기반으로 스프링 IoC에서 제공하는 방법을 혼합해 심플하게 해결 가능 -> 스프링 AOP
AbstractAutoProxyCreator - Bean 인스턴스를 만든 뒤 이를 감싸는 AOP proxy Bean을 만들어주는 역할을 한다
스프링 AOP
----------------------
Null-Safety
스프링 5부터 추가된 Null 관련 Annotation
@NonNull - Null 불가
@Nullable
@NonNullApi(패키지 레벨 설정)
@NonNullField(패키지 레벨 설정)
Preference의 Build, Excution, Deployment의 Compiler에서 Configure annotaions를 사용하여 설정해줘야 한다
'Spring' 카테고리의 다른 글
토비의 스프링 2일차 (0) | 2023.07.15 |
---|---|
토비의 스프링 1일 (0) | 2023.07.14 |
Spring Framework 3 (0) | 2019.12.05 |
Spring Framework 2 (0) | 2019.12.04 |
Spring Framework 1 (0) | 2019.12.04 |