스프링(Spring) #1 - Java 프레임워크로 스프링을 쓰는 이유

햄햄·2023년 3월 5일
1

Spring

목록 보기
1/3
post-custom-banner

출저: https://www.baeldung.com/spring-why-to-choose
위 포스트를 번역 및 요약하였습니다. 의역이 포함되어 있습니다.

왜 프레임워크를 써야 할까?

사실 개발을 하기 위해 프레임워크를 반드시 사용해야 하는 것은 아니다. 하지만 다음과 같은 이유로 프레임워크를 사용하는 것이 좋다.

  • 업무와 관련된 보일러플레이트가 아닌 핵심 업무에 집중할 수 있도록 도와준다.
  • 디자인 패턴의 형태로 수년간의 지혜를 한데 모을 수 있다.
  • 업계 및 규제 표준을 준수하는 데 도움이 된다.
  • 애플리케이션을 만들고 유지보수 하는 데 비용이 절감된다.

이 이점들은 무시하기 어렵다. 하지만 모든 것이 긍정적일 수는 없다. 단점은 무엇이 있을까?

  • 특정 방식으로 애플리케이션을 만들도록 강제한다.
  • 특정 버전의 언어 및 라이브러리에 바인딩된다.
  • 애플리케이션의 리소스 비용을 추가한다.

사실 소프트웨어 개발에는 실버불렛이 없으며 프레임워크도 예외는 아니다. 따라서 어떤 프레임워크를 사용할지 또는 사용하지 않을지는 상황에 따라 선택해야 한다.

스프링 생태계에 대한 요약

스프링은 Java를 위한 IoC(Inversion of Control) 컨테이너로 시작되었다. 이 컨테이너는 스프링과 스프링 위에 개발된 다른 프로젝트의 핵심이 된다.

스프링 프레임워크

스프링 프레임워크는 모듈로 나누어져 있어 어떤 애플리케이션에서든 원하는 부분을 쉽게 골라 사용할 수 있다.

  • 코어(Core): DI(Dependency Injection), 국제화, 유효성 검사, AOP(Aspect Oriented Programming)와 같은 핵심 기능을 제공한다.
  • 데이터 접근(Data Access): JTA(Java Transaction API), JPA(Java Persistence API), JDBC(Java Database Connectivity)를 통한 데이터 접근을 지원한다.
  • 웹(Web): 서블릿 API(Spring MVC)와 최근의 리액티브 API(Spring WebFlux)를 모두 지원하며, WebSockets, STOMP, WebClient를 추가로 지원한다.
  • 통합(Interation): JMS(Java Message Service), JMX(Java Management Extension), RMI(Remote Method Invocation)를 통해 Enterprise Java와의 통합을 지원한다.
  • 테스트(Test): 목 객체, 테스트 픽스처, 컨텍스트 관리 및 캐싱을 통해 단위 및 통합 테스트를 폭넓게 지원한다.

스프링 프로젝트

수년 동안 스프링을 중심으로 성장하고 활발하게 진화하고 있는 강력한 생태계는 스프링을 훨씬 더 가치있게 만든다. 이러한 생태계는 스프링 프레임워크 위에서 개발된 스프링 프로젝트들로 구성된다.

  • Boot: 스프링을 기반으로 다양한 프로젝트를 바로 생성할 수 있는 확장 가능한 템플릿 세트를 제공한다. 임베디드 Tomcat 또는 유사한 컨테이너를 사용하여 독립형 스프링 애플리케이션을 매우 쉽게 만들 수 있다.
  • Cloud: 서비스 검색, 서킷 브레이커, API 게이트웨이와 같은 분산 시스템 패턴을 쉽게 개발할 수 있도록 지원한다. 로컬, 원격, 관리형 플랫폼에서 이러한 보일러플레이트 패턴을 배포하는 데 드는 노력을 줄일 수 있다.
  • Security: 스프링 기반 프로젝트에 대한 인증(Authentication) 및 권한 부여(Autorization)를 사용자가 정의한 방식으로 개발할 수 있는 강력한 메커니즘을 제공한다. 최소한의 선언으로 세션 고정, 클릭 재킹, 사이트 간 요청 위조와 같은 공격으로부터 보호할 수 있다.
  • Mobile: 디바이스를 감지하고 그에 따라 애플리케이션 동작을 조정하는 기능을 제공한다.
  • Batch: 배치 애플리케이션을 개발하기 위한 경량 프레임워크를 제공한다. 스케쥴링, 재시작, 건너뛰기(skipping), 메트릭 수집 및 로깅을 직관적으로 지원한다. 또한 최적화 및 파티셔닝을 통해 대량 작업을 위한 확장도 지원한다.

스프링 인 액션

일반적으로 새로운 기술을 이해할 땐 헬로-월드 프로그램을 생성한다.
Spring을 사용하여 쉽게 헬로-월드 이상의 기능을 수행하는 프로그램을 작성하는 법을 살펴보자. 인메모리 데이터베이스에 의해 지원되는 Employee와 같은 도메인 엔티티에 대해 CRUD 동작을 REST API로 드러내는 애플리케이션을 만들어볼 것이다. 또한 기본 인증을 사용하여 mutation 엔드포인트를 보호할 것이다. 마지막으로, 좋은 단위 테스트와 함께 애플리케이션을 완성한다.

프로젝트 설정

Spring Initializr를 사용하여 Spring Boot 프로젝트를 설정하한다. Web, JPA, H2 및 Security를 프로젝트 의존성에 추가하여 Maven 구성을 올바르게 설정한다.

도메인 모델 및 영속성

먼저 Employee를 간단한 JPA 엔티티로 정의해보자.

@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @NotNull
    private String firstName;
    @NotNull
    private String lastName;
    // Standard constructor, getters and setters
}

엔티티 정의에 auto-generated id가 포함되었다는 것을 참고하자.

이제 엔티티에 대한 JPA 리파지토리를 정의해야 한다. 스프링은 이 과정을 매우 간단하게 만들어준다.

public interface EmployeeRepository 
  extends CrudRepository<Employee, Long> {
    List<Employee> findAll();
}

이와 같은 인터페이스를 정의하기만 하면 Spring JPA가 디폴트값과 사용자가 정의한 작동으로 구체화된 구현을 제공한다.

컨트롤러

이제 들어오는 요청을 라우팅하고 처리할 웹 컨트롤러를 정의해야 한다.

@RestController
public class EmployeeController {
    @Autowired
    private EmployeeRepository repository;
    @GetMapping("/employees")
    public List<Employee> getEmployees() {
        return repository.findAll();
    }
    // Other CRUD endpoints handlers
}

클래스에 어노테이션을 달고 각 핸들러 메서드에 라우팅 메타 정보를 정의하기만 하면 된다.

Security

생성 또는 삭제와 같은 작업을 보안하기 위해서 해당 엔드포인트에 인증되지 않은 액세스를 허용하지 않도록 한다.

@EnableWebSecurity
public class WebSecurityConfig {
 
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
          .authorizeRequests()
            .antMatchers(HttpMethod.GET, "/employees", "/employees/**")
            .permitAll()
          .anyRequest()
            .authenticated()
          .and()
            .httpBasic();
        return http.build();
    }
    // other necessary beans and definitions
}

테스팅

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class EmployeeControllerTests {
    @Autowired
    private MockMvc mvc;
    @Test
    @WithMockUser()
    public void givenNoEmployee_whenCreateEmployee_thenEmployeeCreated() throws Exception {
        mvc.perform(post("/employees").content(
            new ObjectMapper().writeValueAsString(new Employee("First", "Last"))
            .with(csrf()))
          .contentType(MediaType.APPLICATION_JSON)
          .accept(MediaType.APPLICATION_JSON))
          .andExpect(MockMvcResultMatchers.status()
            .isCreated())
          .andExpect(jsonPath("$.firstName", is("First")))
          .andExpect(jsonPath("$.lastName", is("Last")));
    }
    // other tests as necessary
}

애플리케이션 실행

이 애플리케이션을 일반 애플리케이션으로 패키징하고 전통적인 방법으로 서블릿 컨테이너에 배포할 수 있겠지만, Spring Boot가 내장된 Tomcat 서버를 제공한다.

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

이 클래스는 부트스트랩의 일부로, 미리 생성된 클래스이며 내장된 서버를 사용하여 이 애플리케이션을 시작하는 데 필요한 모든 세부 정보를 포함하였다. 또한 이 클래스는 고도로 커스텀할 수 있다.

그렇다면, 왜 스프링을 써야할까?

이제 우리는 프레임워크가 복잡한 엔터프라이즈 애플리케이션을 개발하는 데 어떤 도움을 줄 수 있는지 잘 알고 있다. 또한 웹, 데이터 액세스, 프레임워크 통합에 대해서도 잘 알고 있다. 그렇다면 스프링은 어디에서 빛을 발하는걸까? 한번 살펴보자.

사용성

프레임워크가 인기를 얻는 핵심 요소 중 하나는 개발자가 얼마나 쉽게 사용할 수 있느냐이다. 다양한 구성 옵션과 구성에 대한 규칙이 있는 스프링을 통해 개발자가 정말 쉽게 시작하고 필요한 것을 정확하게 구성할 수 있다.
스프링 부트와 같은 프로젝트는 스프링 프로젝트의 복잡한 초기 설정을 간편하게 만들었다. 또한 누구나 쉽게 사용할 수 있는 훌륭한 문서와 튜토리얼이 있다.

모듈성

스프링의 또 다른 핵심 요소는 고도로 모듈화된 특성이다. 전체 스프링 프레임워크를 사용할지, 아니면 필요한 모듈만 사용할지 선택할 수 있다. 또한 필요에 따라 하나 이상의 스프링 프로젝트를 선택적으로 포함할 수도 있다. 뿐만 아니라 Hibernate나 Struts와 같은 다른 프레임워크도 사용할 수 있다.

적합성

스프링은 Jakarta EE 사양을 모두 지원하지는 않지만, 모든 기술을 지원하며, 필요한 경우 표준 사양보다 개선하는 경우도 많다. 예를 들어, 스프링은 JPA 기반 리포지토리를 지원하므로 프로바이더를 쉽게 전환할 수 있다.

테스트 가능성

프레임워크의 채택 여부는 그 위에 구축된 애플리케이션을 얼마나 쉽게 테스트할 수 있는지에 따라 크게 달라진다. 스프링은 테스트 주도 개발(TDD)를 지향하고 지원한다. 스프링 애플리케이션은 대부분 POJO로 구성되므로 단위 테스트가 상대적으로 훨씬 간단해진다. 또한 단위 테스트가 복잡해지는 MVC 같은 경우를 위해 목 객체를 제공하기도 한다.

성숙도

스프링은 혁신, 채택, 표준화의 오랜 역사를 가지고 있다. 수년에 걸쳐 대규모 엔터프라이즈 애플리케이션 개발에서 직면하는 대부분의 문제에 대한 기본 솔루션이 될만큼 성숙해졌다. 더욱 흥미로운 점은 얼마나 활발하게 개발 및 유지보수가 되고 있는지이다. 새로운 언어 기능과 엔터프라이즈 통합 솔루션에 대한 지원이 매일 개발되고 있다.

커뮤니티의 지원

마지막으로, 모든 프레임워크나 라이브러리는 혁신을 통해 업계에서 살아남을 수 있으며 커뮤니티보다 더 좋은 혁신의 장은 없다. 스프링은 피보탈 소프트웨어가 주도하고 조직과 개인 개발자로 구성된 대규모 컨소시엄의 지원을 받는 오픈 소스이다.

스프링을 쓰지 말아야 할 이유

스프링은 애플리케이션 개발의 복잡성을 관리한다는 점을 기억해야 한다. 시간이 지남에 따라 애플리케이션이 성장하고, 이를 유지 보수할 수 있도록 도와준다. 하지만 그 대가로 리소스를 추가로 사용하고 러닝 커브를 거쳐야 한다. 애플리케이션이 충분히 단순하고 복잡해지지 않을 것으로 예상되면 프레임워크를 전혀 사용하지 않는 것이 더 유리할 수도 있다.

결론

소프트웨어 개발에는 일반적으로 모든 것을 충족하는 하나의 해결책은 없다. 따라서 해결하고자 하는 특정 문제에 대해 가장 간단한 해결책을 선택하는 데 지혜를 발휘해야 한다.

profile
@Ktown4u 개발자
post-custom-banner

0개의 댓글