-
Spring 의 새로운 클래스카테고리 없음 2023. 4. 23. 14:05
오늘 이야기 할 내용은 Spring과 Spring boot의 새로운 클래스에 대해서 알아보려고 한다. 제목은 Spring 이라고 했지만 Spring boot 도 포함되어 있다. 대략 4가지 정도 클래스를 알아볼 예정인데 각 설명마다 프로젝트와 버전을 명시하겠다.
보다 많은 클래스가 추가 되었지만 다 알아 볼 수도 없고 또 한 클래스들이 디펜더시도 있어 유틸성의 클래스들만 알아보도록 하자.
DataSize
DataSize 클래스는 Spring 5.1에 포함될 예정이다. 아직 릴리즈는 되지 않았지만 util 클래스라 크게 바뀌지 않을 듯으로 보인다. 한번 알아보도록 하자.
DataSize dataSize = DataSize.of(10, DataUnit.TERABYTES); System.out.println(dataSize); System.out.println(dataSize.toGigaBytes());
아주 간단하다. 특정한 DataSize를 작성하면 그에 맞게 원하는 데이터 형식으로 바꿔준다. 위의 코드는
10테라
바이트를 기가 바이트로 바꾸어 리턴해주는 코드이다. 실제로 내부적으로는 long 형태의 byte 로 저장하고 있다. 지금 현제 지원해주는 단위는BYTES
,KILOBYTES
,MEGABYTES
,GIGABYTES
,TERABYTES
를 지원해주 고 있다. 뭐 아직까지는 테라바이트 이상으로는 필요 없을 듯으로 판단하여 그런듯 하다.위의 예제는
of
메서드를 이용해서 생성했지만 굳이 그럴 필요 없이ofXXX
메서드를 이용해서 사용하면 더욱 편리하다.DataSize bytes = DataSize.ofBytes(100); DataSize kiloBytes = DataSize.ofKiloBytes(100); DataSize megaBytes = DataSize.ofMegaBytes(100); DataSize gigaBytes = DataSize.ofGigaBytes(100); DataSize teraBytes = DataSize.ofTeraBytes(100);
좀 더 간편하게 사용할 수 있을 듯하다. 이것은 Spring에서 지원해주는 클래스지만 Spring boot 2.1에서도 직접적으로 사용할 수 있다.
@ConfigurationProperties("foo") public class DataSizeProperties { private DataSize tempSize; public DataSize getTempSize() { return tempSize; } public void setTempSize(DataSize tempSize) { this.tempSize = tempSize; } }
우리가 자주 사용하는
@ConfigurationProperties
어노테이션에서도DataSize
클래스를 사용해서 매핑할 수 있다.사용법은 아래와 같이 간단하다.
foo.temp-size=10 foo.temp-size=10MB foo.temp-size=10GB ...
기본적으로 아무 단위가 없다면 Byte로 설정된다. 만약 원하는 단위가 있다면 위 처럼 해당 단위를 작성해주면 된다. 하지만 여기서 주의할 점은 모두 대문자를 이용해야 한다는 것이다. 왜소문자는 파싱을 안되게 했을까? 흠흠 Enum 타입에 있는 문자로 결정하는 것 같은데 자세히는 살펴보지 않았다. 아무튼 그렇다.
만약 해당 타입을 기본적인 단위로 지정해주고 싶다면 다음과 같이작성해도 무방하다.
@ConfigurationProperties("foo") public class DataSizeProperties { @DataSizeUnit(DataUnit.GIGABYTES) private DataSize tempSize; public DataSize getTempSize() { return tempSize; } public void setTempSize(DataSize tempSize) { this.tempSize = tempSize; } }
위와 같이
@DataSizeUnit
어노테이션을 이용해서 해당 단위를 기본적으로 설정 할 수 있다. 그러면 프로퍼티에 굳이 해당 단위를 명시해주지 않아도 된다. 만약 명시해준다면 기본타입은 무시가 되고 작성한 타입으로 동작된다.AnnotatedClassFinder
이 클래스는 Spring boot 2.1 에 새롭게 나타난 클래스이다. 그렇다고 해서 완전하게 새로운 클래스는 아니다.(?) 기존의 있던
SpringBootConfigurationFinder
클래스를 살짝 변경한? 클래스이다. 기존에는@SpringBootConfiguration
어노테이션만을 파싱하기 위한 클래스라면AnnotatedClassFinder
클래스 경우에는 원하는 어노테이션을 파싱할 수 있다.SpringBootConfigurationFinder() { this.scanner = new ClassPathScanningCandidateComponentProvider(false); this.scanner.addIncludeFilter( new AnnotationTypeFilter(SpringBootConfiguration.class)); this.scanner.setResourcePattern("*.class"); }
위의 코드는 기존의 클래스이며 아래의 코드는 새롭게 탄생한 코드이다.
public AnnotatedClassFinder(Class<? extends Annotation> annotationType) { Assert.notNull(annotationType, "AnnotationType must not be null"); this.annotationType = annotationType; this.scanner = new ClassPathScanningCandidateComponentProvider(false); this.scanner.addIncludeFilter(new AnnotationTypeFilter(annotationType)); this.scanner.setResourcePattern("*.class"); }
차이라곤 뭐 생성자에 어노테이션을 받는 부분이 추가 된 것 뿐이다.
사용법은 해당 클래스를 보면 쉽게 알 것 같다. 그래서 생략 하겠다..
PropertyMapper
PropertyMapper
클래스는 Spring boot 2.0 에서 추가된 클래스이다.
이 클래스의 용도는 프로퍼티들을 매핑 시켜주는? 그런 역할을 하는 클래스이다. 예를들어 Spring boot 의@ConfigurationProperties
를 사용해서 프로퍼티들을 매핑 시켰다면 그 이후에 그 프로퍼티들을 실제 사용하는 프로퍼티에 매핑을 시켜주는 그런? 클래스이다. 흠 말로는 어려우니 코드를 살펴보도록 하자.class FooProperties { private int timeout; public void setTimeout(int timeout) { this.timeout = timeout; } public int getTimeout() { return timeout; } } class FooTemplate { private int timeout; public void setTimeout(int timeout) { this.timeout = timeout; } public void bar() { //... //this.timeout } }
예를 들어 위와 같은 클래스가 있다고 가정하자.
FooProperties
클래스는 클라이언트로부터 프로퍼티를 받는 클래스이고FooTemplate
은 실제 그 프로퍼티로 어떤 작업등을 하는 클래스라고 가정해보자. 그럼 다음과 같이 사용할 수 있다.PropertyMapper map = PropertyMapper.get(); FooProperties properties = new FooProperties(); properties.setTimeout(10); FooTemplate fooTemplate = new FooTemplate(); map.from(properties::getTimeout).to(fooTemplate::setTimeout);
위와 같이
FooProperties
클래스로 부터 받은 프로퍼티를FooTemplate
의 속성으로 넣는 작업이다. 실제로FooTemplate
의 timeout 속성에는 10이라는 값이 들어가 있다.또한 좀 더 나은 방식도 제공해준다. 예를들어
source
의 프로퍼티가 null일 경우에 굳이target
프로퍼티에게 null을 넣을 필요가 없다면 다음과 같이 작성하면 된다.map.from(properties::getTimeout).whenNonNull().to(fooTemplate::setTimeout);
그러면 fooTemplate 클래스에 timeout은 영향 받지 않는다. 또한 간단하게 타입도 변경할 수 있다. 예를들어
FooTemplate
의 timeout의 속성이 String이라면 다음과 같이 타입도 변경할 수 있다.map.from(properties::getTimeout).as(String::valueOf).to(fooTemplate::setTimeout);
필자가 말한 위의 메서드뿐만아니라 많은 메서드가 존재하니 필요하다면 한번씩 살펴보는 것도 나쁘지 않다.
TestPropertyValues
이 클래스는 Spring boot 2.0에 새로생긴 클래스 이다. 하지만 우리가 딱히 직접적으로 사용할 클래스는 아니다. 기존의 존재했던 클래스 (EnvironmentTestUtils) 클래스가 Deprecated 되고 해당 클래스가 생겼다.
예전에 Test 할 때 주로 EnvironmentTestUtils.addEnvironment 메서드를 사용했지만 이제는 TestPropertyValues를 사용하면 되는데 해당 클래스를 직접적으로 사용할 일은 없다. 뭐 있을 수는 있겠지만 딱히 커스텀하게 만들지 않는 이상은..
왜냐하면 기존의 Config를 테스트 하던 클래스가 Spring boot 2.0 부터 새롭게 바뀌면서
ApplicationContextRunner
를 이용하면 되기 때문이다.예전에 RC 버전일때 포스팅한 내용은 여기있다. 궁금하다면 참고하면 되겠다.
여기에 존재하는
withPropertyValues
가 내부적으로 바로 TestPropertyValues 이다. 하지만 우리는 그냥 String 타입으로 넘겨서 알아채지 못했을 수도 있다.private final TestPropertyValues environmentProperties; //... public SELF withPropertyValues(String... pairs) { return newInstance(this.contextFactory, this.initializers, this.environmentProperties.and(pairs), this.systemProperties, this.classLoader, this.parent, this.configurations); }
딱히 사용할일은 없지만 그래도 이런게 있다고는 알아봤다. 오늘 내용은 Spring 의 새로운 클래스들을 몇개 알아봤다. 물론 다 알아 보고 싶지만 그러지 못한다. 깊은 내용의 클래스들도 있고 뭐가 뭔지 모르는 클래스도 있고 아직 확인 못한 클래스도 있으니.. 오늘은 여기까지만 알아보도록 하자. 추후에 더 알아 볼 수 있으면 알아보도록 하자.
유틸성 클래스들이라 해당 클래스 직접사용해봐도 쉽게 이해할 수 있을 것으로 판단 된다.
그럼 오늘은 이만!