개인 공부 목적이며 상업적 용도가 아님을 밝힙니다.
강의를 들으며 추가로 궁금한 내용 및 오류를 정리한 글 입니다.
장점: 필요한 클래스만 구현해서 테스트를 진행할 수 있다.
POJO란 Plain Old Java Object 로 오래된 순수 자바 객체를 의미한다.
이는 특정 기술에 종속되지 않고 객체지향원리에 충실하면서 재활용될 수 있는 설계가 가능한 객체 를 의미한다.
< POJO 예시 코드>
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
// 게터와 세터 메서드
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
특정 라이브러리 등에 종속하는게 아니라 순수 자바 기술로 구현한 객체
<POJO가 아닌 예시 코드 - ORM 프레임워크 사용을 위한 상속/구현 처리 >
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class Main {
public static void main(String[] args) {
// Hibernate 설정 로드
Configuration configuration = new Configuration().configure();
// 세션 팩토리 생성
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 세션 생성
Session session = sessionFactory.openSession();
// 트랜잭션 시작
Transaction transaction = session.beginTransaction();
// 데이터베이스에 저장할 객체 생성
Employee employee = new Employee("John Doe", 30);
등등등....
POJO보다 많은 설정이 필요하고, 종속하므로 객체지향적인 장점을 살리기 어려움
}
}
스프링 프레임워크가 POJO를 지향하는 프레임워크인 예시
<JPA를 사용한 코드>
import javax.persistence.*;
@Entity //이 클래스는 Hibernate의 엔터티임을 의미
@Table(name = "employees") //매핑될 테이블 이름
public class Employee {
@Id //기본키(Primary key)
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "employee_id") //테이블의 매핑될 컬럼
private Long id;
@Column(name = "employee_name")
private String name;
@Column(name = "employee_age")
private int age;
// 기본 생성자
public Employee() {
}
// 매개변수가 있는 생성자
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
// 게터와 세터 메서드
public Long getId() {
return id;
}
...
이렇게 어노테이션을 활용해서 객체와 DB간 매핑을 자동 처리
POJO보다 많은 설정을 필요로 하지만
그래도. 객체지향적인 프로그래밍을 유지하면서 사용하고 있음
}
이런 JPA 같은 것을 PSA (Portable Service Abstraction)이라고 하며
이는 Spring의 3대 원리중 하나이다 (AOP , IoC/DI , PSA )
PSA란, 여러 구현체에서 일관된 방식으로 서비스가 가능하도록 추상화된 인터페이스 를 제공한다. JPA도 DB와 자바 객체간의 매핑을 위한 인터페이스를 제공하는 것이다.
POJO는 순수 자바로 구현되어 재활용이 가능한 객체이고 , JAVA EE 에서 점점 무거워지는 객체에 대해 반발하여 발생하였다. 여러 의존성으로 인해 객체 지향의 이점이 사라지는 것을 막기 위해 Spring은 최대한 POJO 지향적으로 갈 수 있도록 PSA 등의 기술을 이용하여 이를 구현하고 있다.
강의에서 POJO 방식으로 테스트 케이스를 구현하는데 테스트 상단에
@SpringBootTest 어노테이션이 있었다.

이는 실제 애플리케이션이 구동되는 것과 동일하게 Spring Boot의 전체 컨텍스트를 로드하여 테스트하는 것으로 통합테스트 환경이 가능하다. (<-> 단위테스트)
강의에서 class 를 record 타입으로 바꾸는 것을 보고 어떤 역할을 하는지 궁금해졌다. 아래는 class타입을 record 타입으로 변경한 코드 예시이다.
<변경 전 코드>
private class AddProductRequest { //private 클래스타입
private final String name ;
private final int price ;
private final DiscountPolicy discountPolicy;
//생성자
public AddProductRequest(final String name , final int price , final DiscountPolicy discountPolicy) {
Assert.hasText(name , "상품명은 필수입니다.");
Assert.isTrue(price > 0 , "상품 가격은 0보다 커야 합니다.");
Assert.notNull(discountPolicy , "할인 정책은 필수입니다.");
this.name = name;
this.price = price;
this.discountPolicy = discountPolicy;
}
}
<변경 후 코드>
//record 타입 변경 후 코드
//1. class 에서 record 로 타입이 바뀜
//2. 매개변수에서 final이 사라짐
private record AddProductRequest(String name , int price , DiscountPolicy discountPolicy) {
private AddProductRequest {
Assert.hasText(name, "상품명은 필수입니다."); //null도 text로 잡힐까??
Assert.isTrue(price > 0, "상품 가격은 0보다 커야 합니다."); //false이면 msg 출력인가?
Assert.notNull(discountPolicy, "할인 정책은 필수입니다.");
this.name = name;
this.price = price;
this.discountPolicy = discountPolicy;
}
}
매개변수(필드) , 생성자, getter , setter등을 알아서 세팅해준다
모든 필드는 자동으로 final처리가 되어 한번만 초기화가 가능하다. (불변성)
자동으로 equals() , toString() 등의 메서드가 Override 되어있다.
결론 : DTO혹은 VO 같은 데이터를 저장하는 객체를 간결하고 불변적인 성질로 편하게 만들어준다.
테스트 코드에 inner class로 필요한 기능들을 테스트하고 이후에 외부로 쉽게 꺼내는 탭메뉴가 있어 신기했다.
예) enum DiscountPolicy 클래스를 외부 클래스로 빼기 (move Inner Class ..)
그리고 추출한 class를 main으로 올리면 좀 더 스무스한 테스트->운영 코드 전환이 되는 것 같다. (class선택 > refactoring > move class > main으로 이동)

main에 설정되어 있는 것을 보고 어떤 기능을 하는지 궁금해서 정리했다.

@SpringBootApplication = SpringBoot Application으로 설정하기 위한 어노테이션
이 어노테이션에는
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan 어노테이션 등을 포함하고 있다.
@EnableAutoConfiguration
@ComponentScan
종합적으로 보면 @SpringBootApplication는 Bean으로 설정되었거나, 자주 사용되는 빈들을 자동으로 스프링 컨테이너에 주입해서 개발자들이 편하게 개발할 수 있는 환경을 제공하는 어노테이션이다.