본 가이드는 fw spring Lombok 핵심 가이드 및 실전 아키텍처의 핵심 개념, 실전 구성 명령어 및 아키텍처 베스트 프랙티스를 다룹니다. 클라우드 네이티브 및 인프라 엔지니어링 실무에 즉시 활용 가능하도록 체계적으로 정리했습니다.
Common
Annotation
Class에 @Data 애노테이션을 추가하면 toString() 등 활용도 높은 메서드를 사용할 수 있다.
@Data //아래의 모든 애노테이션을 포함하는 문법
// @Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor
@NoArgsConstructor //파라미터가 없는 기본생성자 자동 선언
@AllArgsConstructor //모든 파라미터를 명시하는 기본생성자 자동 선언
@RequiredArgsConstructor //final이나 @NonNull인 필드 값만 파라미터로 받는 생성자 만듦
Method
public class DataExample {
private final String name;
private int age;
private double score;
private String[] tags;
public DataExample(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
public void setScore(double score) {
this.score = score;
}
public double getScore() {
return this.score;
}
public String[] getTags() {
return this.tags;
}
public void setTags(String[] tags) {
this.tags = tags;
}
@Override public String toString() {
return "DataExample(" + this.getName() + ", " + this.getAge() + ", " + this.getScore() + ", " + Arrays.deepToString(this.getTags()) + ")";
}
protected boolean canEqual(Object other) {
return other instanceof DataExample;
}
@Override public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof DataExample)) return false;
DataExample other = (DataExample) o;
if (!other.canEqual((Object)this)) return false;
if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;
if (this.getAge() != other.getAge()) return false;
if (Double.compare(this.getScore(), other.getScore()) != 0) return false;
if (!Arrays.deepEquals(this.getTags(), other.getTags())) return false;
return true;
}
@Override public int hashCode() {
final int PRIME = 59;
int result = 1;
final long temp1 = Double.doubleToLongBits(this.getScore());
result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());
result = (result*PRIME) + this.getAge();
result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));
result = (result*PRIME) + Arrays.deepHashCode(this.getTags());
return result;
}
public static class Exercise<T> {
private final String name;
private final T value;
private Exercise(String name, T value) {
this.name = name;
this.value = value;
}
public static <T> Exercise<T> of(String name, T value) {
return new Exercise<T>(name, value);
}
public String getName() {
return this.name;
}
public T getValue() {
return this.value;
}
@Override public String toString() {
return "Exercise(name=" + this.getName() + ", value=" + this.getValue() + ")";
}
protected boolean canEqual(Object other) {
return other instanceof Exercise;
}
@Override public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Exercise)) return false;
Exercise<?> other = (Exercise<?>) o;
if (!other.canEqual((Object)this)) return false;
if (this.getName() == null ? other.getValue() != null : !this.getName().equals(other.getName())) return false;
if (this.getValue() == null ? other.getValue() != null : !this.getValue().equals(other.getValue())) return false;
return true;
}
@Override public int hashCode() {
final int PRIME = 59;
int result = 1;
result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());
result = (result*PRIME) + (this.getValue() == null ? 43 : this.getValue().hashCode());
return result;
}
}
}
Feature
@RequiredArgsConstructor: 인터페이스 구현시 의존성 주입 자동화
GPT
> 💡
\[질문\]
@RequiredArgsConstructor
public class JobService \{
private final Job calculateServiceInstanceRunningTimeJob;
private final Job serviceInstanceStateCheckJob;
서비스가 이런식으로 정의되었다면 기본적으로 의존성 주입을 하여
public class CalculateServiceInstanceRunningTimeJob implements Job 클래스를 calculateServiceInstanceRunningTimeJob에 할당하고,
public class ServiceInstanceStateCheckJob implements Job 클래스를 serviceInstanceStateCheckJob에 할당할것이라고 보아도 되겠는가?
\[답변\]
네, 맞습니다. @RequiredArgsConstructor가 적용된 클래스에서는 해당 클래스의 final 필드를 매개변수로 받는 생성자가 자동으로 생성됩니다. 이 생성자는 주입 받은 매개변수에 따라 해당 필드에 값을 할당하게 됩니다.
따라서, 예를 들어 다음과 같은 코드가 있다면:
javaCopy code
@RequiredArgsConstructor
public class JobService {
private final Job calculateServiceInstanceRunningTimeJob;
private final Job serviceInstanceStateCheckJob;
// ...
}
Spring의 빈으로 등록된 JobService 클래스는 이 두 필드를 생성자를 통해 주입받습니다. 이때, Spring은 각 필드의 타입을 보고 알맞은 빈을 찾아서 주입하게 됩니다. 따라서 calculateServiceInstanceRunningTimeJob 필드에는 CalculateServiceInstanceRunningTimeJob 클래스의 인스턴스가, 그리고 serviceInstanceStateCheckJob 필드에는 ServiceInstanceStateCheckJob 클래스의 인스턴스가 주입될 것입니다.
– 시사하는 점
– Bean 등록시 Default Qualifier
– Class명 변수명 (소문자 시작)
– (수동) Bean 등록
– @Component
– (수동) Service Constructor
@Autowired
public MyService(@Qualifier("implementationA") MyInterface implementationA,
@Qualifier("implementationB") MyInterface implementationB) {
this.implementationA = implementationA;
this.implementationB = implementationB;
}
Leave a Reply