jdk8 이후 문법 공부 안하셨죠?(저도 그래요😄) Amber 프로젝트를 알면 Java의 주요 언어 변경사항에 대해 쭉 정리가 됩니다.
## Project Amber
- 소개
Project Amber의 목표는 [OpenJDK JEP 프로세스](https://openjdk.org/jeps/1) 에서 JEP 후보로 승인된 더 작고 생산성 지향적인 Java 언어 기능을 탐색하고 배양하는 것입니다 . 이 프로젝트는 [컴파일러 그룹](https://openjdk.org/groups/compiler) 의 후원을 받습니다 .
대부분의 Project Amber 기능은 Java 플랫폼의 공식 부분이 되기 전에 최소한 두 번의 [_미리보기를 거칩니다._](https://openjdk.org/jeps/12) 특정 기능에 대해 각 미리보기 라운드와 최종 표준화를 위한 별도의 JEP가 있습니다. 이 페이지는 기능에 대한 최신 JEP에만 연결됩니다. 이러한 JEP에는 해당 기능에 대한 이전 JEP에 대한 링크가 있을 수 있습니다.
(https://openjdk.org/projects/amber/ 에서 발췌 번역함)
[!NOTE] JEP
- JDK Enhancement-Proposal & Roadmap Process
- amber 프로젝트는 이런 실험적인 생각들을 배양하는 프로젝트이다.
- JSR로 발전할 수 도 있고 아닐 수도 있다.
- 진행중인 JEP들을 가만히 보면 Javascript의 구조할당분해 기능과 유사한 제안이 많다. Python에도 유사 기능이 있다.
```js
const { name, age } = { name: 'matthew', age: 23 }
```
- record는 데이터 전달 객체를 많이 다루는 java 에서 불변객체로 만들기 위한 노력이 많이 드는 것을 극복하기 위해 만들어졌다.
```java
class Point {
private final int x;
private final int y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
int x() { return x; }
int y() { return y; }
public boolean equals(Object o) {
if (!(o instanceof Point)) return false;
Point other = (Point) o;
return other.x == x && other.y = y;
}
public int hashCode() {
return Objects.hash(x, y);
}
public String toString() {
return String.format("Point[x=%d, y=%d]", x, y);
}
}
```
- "var"라는게 있는지 모르는 개발자도 많을 걸?
```java
// jdk 10
var list = new ArrayList<String>(); // infers ArrayList<String>
var stream = list.stream(); // infers Stream<String>
// jdk 11 부터는 람다식에도 쓸 수 있다.
(var x, var y) -> x.process(y)
// 람다식은 원래 타입추론이므로 적어줄 필요가 없는데
// 굳이 var를 적어줘야하는 이유는 아래처럼 annotation을 쓸 수 있다.
@Nonnull var x = new Foo();
(@Nonnull var x, @Nullable var y) -> x.process(y)
```
- [JEP 459: String Templates (Second Preview)](https://openjdk.org/jeps/459) 이런 것도 진행중입니다.
## 코딩해봅시다
```java
@RestController
@SpringBootApplication
public class DemoSpringApplication {
public static void main(String[] args) {
SpringApplication.run(DemoSpringApplication.class, args);
}
@GetMapping("/greeting")
public String greeting(@RequestParam String name) {
// arrow, inline : jdk 14 이상
Loan loan = switch(name) {
case "matthew" -> new SecuredLoan();
default -> new UnSecuredLoan(0.0047f);
};
// yield : jdk 14 이상
// pattern matching : jdk 21 이상
String message = switch(loan) {
case SecuredLoan secureLoan -> name + " 무이자“;
case UnSecuredLoan usl -> {
yield name + " : " + usl.interest;
}
};
return message;
}
// sealed 클래스/인터페이스 : jdk 17 이상
// permits 키워드를 이용하여 상속 / 구현 할 클래스를 미리 지정한다.
sealed interface Loan permits SecuredLoan, UnSecuredLoan {}
// seald 클래스 / 인터페이스를 상속 / 구현하는 클래스는 final 필수
final class SecuredLoan implements Loan {}
record UnSecuredLoan (float interest) implements Loan {}
}
```
## when
```java
String s = switch (score) {
case 100 -> "Perfect!";
case Integer i when i >= 90 -> "Very Good!";
case Integer i when i >= 80 -> "Good!";
default -> "Bad";
}
```
## null
```java
return switch(value) {
case null, default -> "default";
case 1 -> A;
case 2 -> B;
}
```
## Record Pattern
```java
// jdk 16
if (obj instanceof Student student) {
student.study();
String name = student.getName():
System.out.println(name);
}
```
```java
// jdk 21
if (obj instanceof Student(String name)) {
student.study();
System.out.println(name);
}
```
## for 문
```java
Iterable<String> iterable = ...;
for (String s: iterable) {
// Do something with s
}
// 이렇게 쓰던걸 아래처럼 ...
///////////////////////////////////////
record Point(double x, double y) {}
List<Points> points = ...;
for (Point(double x, double y): points) {
// Do something with x and y
}
```
Session 대신 JWT를 사용하는 이유 실 서버는 하나의 인스턴트로만 동작하지 않는다. 서버의 고가용성(high availabliity, HA)을 확보하기 위해 두 개 이상의 병렬서버로 운영하게 된다. 서버가 병렬로 운영되는 상황에서 세션을 사용하면 각 서버간의 세션을 동기화하는 문제가 발생한다. 이를 해결하기 위해 공유 데이터베이스를 이용한 세션공유 기법들을 사용하기도 한다. 서버가 많아지면 세션동기는 더 어렵다. JWT를 사용하면 세션사용으로 인한 서버 자체에 부담도 줄이면서 공유 세션에 대한 관리가 한층 수월하다. 스프링 시큐리티 - SecurityConfig.java session을 사용하지 않도록 설정 jwtAuthFilter 추가 httpBasic 제거 - JwtAuthenticationFilter.java config.filter 패키지에 파일 추가 jwt dependency 추가 (3개). gradle refresh하는 거 까먹지 말기 config.service 패키지에 [JwtService.java](http://JwtService.java) 추가 jwtService와 UserDetailService final field 추가. @RequiredArgsConstructor 까먹지 말기 - config.service.JwtService 소스 참조해서 파일 작성 - controller, service 수정 User 를 리턴하면 pwd가 그대로 노출되므로 AuthResponse와 AuthRequest로 교체 Github https://github.com/ohhoonim/factory.git 유튜브 영상 스프링부트 - 보안 JWT JWT - refresh 토큰과 logout
Inlay Hint > Parameter names java.inlayHints.parameterNames.enabled: literals java.inlayHints.parameterTypes.enabled java.inlayHints.variableTypes.enabled editor.inlayHints.enabled: offUnlessPressed Code lens editor.codeLens: true editor.codeLensFontSize java.referencesCodeLens.enabled java.implementationCodeLens: all ligature 폰트 설정 editor.fontFamily: 'D2Coding ligature’ "editor.fontLigatures": true, 편집기 확대 축소 단축키 설정 zoom 으로 검색 Google Style Formatter 설정 java.format.settings.url https://raw.githubusercontent.com/google/styleguide/gh-pages/eclipse-java-google-style.xml JDK 설정 java.configuration.detectJdksAtStart Language Server JAVA_HOME 설정 java.jdt.ls.java.home Gradle JAVA_HOME 설정 java.import.gradle.java.home Installed JDK 설정 java.configuration.runtimes Static 클래스, 메서드 import java.completion.favoriteStaticMembers "org.springframework.test.web.client.match.MockRestRequestMatchers. ", "...
# 5-Step Architecture Spec 이 문서는 헥사고날 아키텍처를 실무적으로 변형하고, DDD의 전략적 설계를 극대화한 5-Step Architecture의 표준 공정을 정의한다. 샘플 리파지토리 : https://github.com/ohhoonim/smart-factory/tree/main/back/factory-api-module ### Core Philosophy > "Service는 배달부(Messenger)일 뿐, 뇌(Brain)는 **Model**에, 법(Law)은 **Policy**에 둔다." > --- ## The 5-Step Standard Process ### Step 1: 도메인 자아 확립 (Domain Model Discovery) 비즈니스의 핵심 상태와 행위를 관리하는 Aggregate Root(AR)를 정의한다. - **원칙**: 데이터 필드가 아닌 '상태 변화의 규칙'과 '생애주기'에 집중한다. - **핵심**: AR 내부에서만 상태 변경이 가능하도록 캡슐화하며, 외부로부터의 직접적인 필드 수정을 금지한다. ### Step 2: 법전 정의 (Policy Abstraction) 비즈니스 제약 조건 중 변하기 쉬운 규칙(보안, 한도, 계산 로직)을 인터페이스로 추상화한다. - **원칙**: 도메인 모델이 프레임워크(Spring)나 환경 설정에 오염되지 않도록 보호한다. - **효과**: 정책의 변경이 모델이나 서비스의 코드 수정을 유발하지 않도록 결합도를 낮춘다. ### Step 3: 도구 제작 (Activity Implementation) 도메인이 외부 세계와 소통하기 위한 구체적인 기술(DB, Storage, 외부 API)을 구현한다. - **원칙**: 헥사고날의 **Output Adapter** 역할을 수행하며, 기술적 복잡성을 이 계층에 가둔다. - **명칭**: `QueryActivity`(조회), `CommandActivity`(...
댓글
댓글 쓰기